为什么即使在进程终止后,异步读取也没有完成
本文关键字:读取 异步 进程 终止 为什么 | 更新日期: 2023-09-27 18:07:00
我写了一个从文件中读取数据作为参数的进程。我异步读取了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,由于它增加了异步功能)。
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
完成后触发。我试图找出如何使用反射器,但我看不见它。不管怎样,我自己也经历过这种事。
这篇文章还告诉了如何处理这个问题的秘密:显然,当没有更多的输入将到来时,事件处理程序将使用null
数据调用。因此,您需要等待这个条件。
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