如何一次异步读取标准输出流和标准错误流

我想在控制台中读取表单中的进程输出(标准输出与一个流中的标准错误混合)。 有办法怎么做?

我正在考虑使用

ProcessStartInfo.UseShellExecute = true; 

但后来我无法异步读取输出。 如果我订

 process.ProcessStartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.OutputDataReceived += new DataReceivedEventHandler(partialOutputHandler); 

然后我可以读取标准输出(我可以做同样的标准错误)但我不知道如何模拟控制台的行为(混合stdout和stderr)。

注意:我知道Linux具有将标准错误流重定向到标准输出流的function,但我无法将其用于.NET。

我必须错过一些非常简单的事情

谢谢!

你的意思是这样的吗?

 SynchronizationContext _syncContext; MyForm() { _syncContext = SynchronizationContext.Current; } void StartProcess() { var process = new Process { StartInfo = new ProcessStartInfo { FileName = "myProcess.exe", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, } }; process.OutputDataReceived += (sender, args) => Display(args.Data); process.ErrorDataReceived += (sender, args) => Display(args.Data); process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); process.WaitForExit(); //you need this in order to flush the output buffer } void Display(string output) { _syncContext.Post(_ => myTextBox.AppendText(output), null); } 

MSDN 文章指出:

可以同步或异步读取重定向的StandardError流。 Read,ReadLine和ReadToEnd等方法对进程的错误输出流执行同步读取操作。 在关联的Process写入其StandardError流或关闭流之前,这些同步读取操作不会完成。

相反,BeginErrorReadLine在StandardError流上启动异步读取操作。 此方法为流输出启用指定的事件处理程序,并立即返回到调用程序,调用程序可以在将流输出定向到事件处理程序时执行其他工作。

同步读取操作在从StandardError流读取调用者和写入该流的子进程之间引入依赖关系。 这些依赖性可能导致死锁条件。 当调用者从子进程的重定向流中读取时,它依赖于子进程。 调用者等待读操作,直到子进程写入流或关闭流。 当子进程写入足够的数据来填充其重定向流时,它依赖于父进程。 子进程等待下一个写操作,直到父进程从完整流中读取或关闭流。 当调用者和子进程等待彼此完成操作时,将导致死锁条件,并且两者都无法继续。 您可以通过评估调用者和子进程之间的依赖关系来避免死锁。

这同样适用于StandardOutput ,因此您只需异步读取两个流。

Merging两个流Merging为一个流会使检测错误报告的输出和“产品”信息变得复杂。

我找到了答案:

输出流被缓冲。 无法获得插入到流中的项的真实顺序。 实际上它没有多大意义,因为两个流也可以同时写入。 它们彼此独立。 因此,您可以做的最好的事情是在每个到达时获得每个顺序输出。

通常这不是问题,因为几乎所有控制台应用程序都使用标准输出来输出和错误消息。 某些应用程序使用错误流,但消息通常与输出流中生成的错误重复。

资料来源: http //social.msdn.microsoft.com/Forums/uk/csharpgeneral/thread/192b6df7-9437-42cf-81c1-c125021735ba