DSomesh Ответов: 1

Процесс.waitforexit () зависает на неопределенное время при перенаправлении вывода процесса


В этом случае я запускаю приложение и считываю его выходное значение с помощью StandardOutput и StandardError и записываю его в файл. после запуска процесса запускаются два разных потока, которые считывают вывод из потока и устанавливают определенные строки, которые используются для записи того же самого в файл outout основным потоком.Иногда (крайне редкий сценарий) процесс.waitforexit () не возвращается и ждет бесконечно.
private Thread outThread = null;
        private Thread errThread = null;
        private string outputText = "";
        private string errorText = "";
        private StreamReader outStream = null;
        private StreamReader errStream = null;

protected void ReadError()
        {
            if (errStream != null) {
                errorText = errStream.ReadToEnd();
            }
        }

        protected void ReadOutput()
        {
            if (outStream != null) {
                outputText = outStream.ReadToEnd();
            }
        }

public int launchProcess(string process, string arguments, StringDictionary env, int timeout, string logfile)
        {
            ProcessStartInfo psi = new ProcessStartInfo();
            psi.Arguments = arguments;
            psi.FileName = process;
            //psi.WindowStyle = ProcessWindowStyle.Hidden;
            psi.UseShellExecute = false;
            if (env != null)
            {
                psi.EnvironmentVariables.Clear();
                foreach (string key in env.Keys)
                {
                    psi.EnvironmentVariables.Add(key, env[key]);
                }
            }

            int time = (timeout == -1) ? int.MaxValue : timeout;

            if (logfile != null && time != 0)
            {
                psi.RedirectStandardOutput = true;
                psi.RedirectStandardError = true;
                psi.RedirectStandardInput = true;
            }

            try
            {
                Process p = Process.Start(psi);
                if (time != 0)
                {
                    if (logfile != null)
                    {
                        outStream = p.StandardOutput;
                        errStream = p.StandardError;
                        outThread = new Thread(new ThreadStart(ReadOutput));
                        errThread = new Thread(new ThreadStart(ReadError));
                        outThread.Start();
                        errThread.Start();
                    }

                    p.WaitForExit(time);

                    if (logfile != null) try
                    {
                        outThread.Join();
                        errThread.Join();
                        File.AppendAllText(logfile,
                            String.Format("Running '{0}' with arguments '{1}'\nStandard Output:\n", process, arguments),
                            Encoding.UTF8);
                        File.AppendAllText(logfile, outputText, Encoding.UTF8);
                        File.AppendAllText(logfile, "\n\nStandard Error:\n", Encoding.UTF8);
                        File.AppendAllText(logfile, errorText, Encoding.UTF8);
                    }catch (Exception e){
                        debugMessage("Error occurred while writing standard output to log: " + e.Message);
                    }

                    if (!p.HasExited)
                    {
                        throw new ProcessTimedOutException(psi.FileName);
                    }
                    return p.ExitCode;
                }
                return 0;
            }
            catch (Exception e)
            {
                debugMessage("Unable to launch process " + process + ". " + e.Message);
                return -1;
            }
        }

Пожалуйста, обратите внимание,что в случае ошибки процесс возвращается только после того, как я вручную убью процесс, так что я предполагаю, что это какая-то тупиковая проблема. Может ли кто-нибудь помочь мне разобраться в этой проблеме здесь?

Что я уже пробовал:

Я прошел через подобные вопросы в c# - ProcessStartInfo висит на "WaitForExit"? Почему? - переполнение стека[^] но не могу понять, есть ли у меня та же проблема.

1 Ответов

Рейтинг:
2

OriginalGriff

Начните с использования отладчика и выясните, что именно вы передаете для обработки.Начать
Что это за процесс? Какие аргументы? Каково значение тайм-аута в конечном итоге?

Если все выглядит правильно, то сначала попробуйте запустить процесс с помощью командной строки CMD: что он делает, что произошло? Кончилось ли оно?
Затем начните вручную настраивать вещи: используйте отладчик, чтобы переопределить тайм-аут на пару секунд, и посмотрите, остановится ли он тогда.

В принципе, играйте с ним: получайте информацию. На данный момент у вас есть код, который так сильно зависит от внешнего мира - как с точки зрения входных параметров, так и конфигурации системы, - и это не работает, потому что какая-то часть из трех (третья-ваш код), которую вам нужно сначала изолировать, где на самом деле проблема, и отладчик-это единственный инструмент, который может помочь вам сделать это. Мы не можем сделать ничего из этого для вас, потому что у нас есть доступ только к одной части триплета: ваш код, как показано выше. И мы не можем запустить это в ваших точных условиях!