为什么即使在进程终止后仍未完成异步读取?

我编写了一个Process,它从作为参数给出的文件中读取数据。 我已同步异步读取StandardOutput和StandardError。

public static string ProcessScript(string command, string arguments) { Process proc = new Process(); proc.StartInfo.UseShellExecute = false; proc.StartInfo.RedirectStandardOutput = true; proc.StartInfo.RedirectStandardError = true; proc.StartInfo.FileName = command; proc.StartInfo.Arguments = arguments; proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; proc.Start(); string error = null; string output = null; proc.OutputDataReceived += (sender, outputLine) => { if (outputLine.Data != null) { output += outputLine.Data; } }; proc.BeginOutputReadLine(); error = proc.StandardError.ReadToEnd(); proc.WaitForExit(); proc.Close(); //I have not got entire Output return output; } 

完成该过程后,我将获得输出。 但并非完全如此。 我只得到部分数据。 即使在进程完成任务之后,异步读取也没有结束,所以只有我得到部分数据。 我需要完整的字符串。

编辑:

我正在使用.Net 3.5。 我不能使用ReadToEndAsync方法

有任何想法吗?

您可以直接从实际输出流中直接读取(假设您使用的是.NET 4.5,这要归功于其添加的异步function),而不是处理事件并处理由此产生的问题。

 public static string ProcessScript(string command, string arguments) { Process proc = new Process(); proc.StartInfo.UseShellExecute = false; proc.StartInfo.RedirectStandardOutput = true; proc.StartInfo.RedirectStandardError = true; proc.StartInfo.FileName = command; proc.StartInfo.Arguments = arguments; proc.Start(); var output = proc.StandardOutput.ReadToEndAsync(); var error = proc.StandardError.ReadToEndAsync(); proc.WaitForExit(); proc.Close(); var errorContent = error.Result; return output.Result; } 

这里由ReadToEndAsync表示的Task在其结果表示的全部数据之前不会实际完成。 这意味着您要等到拥有所有数据而不是等待进程完成 ,因为这两个数据可能不完全相同。

根据这篇文章 ,事件处理程序可能在WaitForExit完成后触发。 我试图找出如何使用Reflector,但我看不到它。 无论如何,我经历过这样的事情。

这篇文章还讲述了如何处理这个问题的秘诀:显然,当没有更多的输入将会出现时,使用null数据调用事件处理程序。 所以你需要等待这种情况。

我认为Servy解决这个问题的方法更胜一筹。 我只是在这里记录这种行为。

重复https://stackoverflow.com/a/25772586/2065863

WaitForExit(timeout)返回true后调用WaitForExit() (无参数):

 if (process.WaitForExit(timeout) && process.WaitForExit()) { // do stuff: async read will be completed here } 

有关详细信息,请阅读此处的评论: https : //msdn.microsoft.com/en-us/library/ty0d8k56(v=vs.110).aspx