Process.Exited никогда не вызывается, хотя EnableRaisingEvents имеет значение true - PullRequest
8 голосов
/ 28 февраля 2012

У меня есть исполняемый файл, который работает нормально, когда я запускаю его вручную, и он существует, как и должно с ожидаемым выводом. Но когда я запускаю его с помощью метода ниже, событие Process.Exited никогда не запускается. Обратите внимание, что я запомнил Process.EnableRaisingEvents

protected override Result Execute(RunExecutable task)
{
    var process = new Process();
    process.StartInfo.Arguments = task.Arguments;
    process.StartInfo.FileName = task.ExecutablePath;
    process.StartInfo.CreateNoWindow = true;
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardOutput = true;
    process.EnableRaisingEvents = true;

    process.Exited += (sender, args) =>
    {
        processSync.OnNext(new Result
        {
            Success = process.ExitCode == 0,
            Message = process.StandardOutput.ReadToEnd()
        });
        processSync.OnCompleted();
    };
    process.Start();

    return processSync.First();;
}

Проблема та же, если я использую Process.WaitForExit () вместо реактивных расширений для ожидания события выхода.

Кроме того, если я запускаю процесс с другим аргументом, который выдает другой вывод, он в порядке.

Кажется, это как-то связано с process.StartInfo.RedirectStandardOutput = true;, так как, когда я отключаю это, оно работает. Но это может быть просто симптомом другой проблемы.

Любая помощь приветствуется: -)

Ответы [ 2 ]

6 голосов
/ 28 февраля 2012

В вашем коде тупик.«Стандартный вывод» - это всего лишь разновидность именованного канала, который имеет небольшой буфер для передачи данных из одного процесса в другой.Если буфер заполнен, процесс записи должен ждать, пока процесс чтения извлечет некоторые данные из буфера.

Таким образом, процесс, который вы запустили, может ждать, пока вы прочитаете из стандартного вывода, но выожидание завершения процесса, прежде чем вы начнете читать -> взаимоблокировка.

Решение заключается в непрерывном чтении во время работы процесса - просто позвоните StandardOutput.ReadToEnd(), прежде чем вызывать WaitForExit().Если вы хотите читать без блокировки текущего потока, вы можете использовать BeginOutputReadLine() и OutputDataReceived события.

1 голос
/ 28 февраля 2012

Очевидно, что вы должны прослушивать поток StandardOutput, если вы перенаправили его, иначе процесс не завершится.Он ожидает, что кто-то сначала прочитает вывод.

Событие Process.Exited не вызывается

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...