#c# #.net
#c# #.net
Вопрос:
Вот код:
var output = new StringWriter();
var error = new StringWriter();
var p = new Process();
p.StartInfo = new ProcessStartInfo
{
WorkingDirectory = workingDir,
FileName = file,
Arguments = args,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
};
p.OutputDataReceived = (o, e) => { output.WriteLine(e.Data); };
p.ErrorDataReceived = (o, e) => { error.WriteLine(e.Data); };
p.Start();
if (!p.WaitForExit((int)timeout.TotalMilliseconds))
{
p.Kill();
throw new Exception("Timeout expired.");
}
string errorData = error.ToString();
if (errorData.Length > 0)
throw new Exception(errorData);
return output.ToString();
Я бы ожидал OutputDataReceived
, ErrorDataReceived
что обработчики and будут вызываться всякий раз, когда данные становятся доступными, однако этого не происходит. Для процесса, который выводит тонну материала в стандартный вывод, этот код в конечном итоге завершается throw new Exception("Timeout expired.");
. Я попытался добавить некоторый отладочный код в обработчики, но он никогда не вызывается. Разве весь смысл указания обработчиков out / err не в том, чтобы вызывать их асинхронно?
Ответ №1:
Из документации:
Событие активируется во время асинхронных операций чтения при стандартном выводе. Чтобы запустить асинхронные операции чтения, вы должны перенаправить поток стандартного вывода процесса, добавить свой обработчик событий в событие OutputDataReceived и вызвать BeginOutputReadLine . После этого событие OutputDataReceived сигнализирует каждый раз, когда процесс записывает строку в перенаправленный поток StandardOutput, пока процесс не завершится или не вызовет CancelOutputRead .
Вы не выполняете никаких асинхронных операций чтения, поэтому событие не будет запущено.
Если вы просто добавите вызов p.BeginOutputReadline()
после запуска процесса, он будет работать. Аналогично, чтобы прочитать поток ошибок, вызовите BeginErrorReadLine()
.
Ответ №2:
Чтобы начать получать события из стандартного вывода и стандартной ошибки, вам нужно вызвать BeginOutputReadLine()
и BeginErrorReadLine()
, соответственно.