我怎么知道最后一个OutputDataReceived何时到达?
时间:2020-03-05 18:53:35 来源:igfitidea点击:
我在针对.Net Framework 3.5的程序中有一个System.Diagnostics.Process对象
我已经重定向了StandardOutput和StandardError管道,并且从它们异步接收数据。我还为Exited事件设置了事件处理程序。
一旦我调用Process.Start()
,我想在等待事件发生时去做其他工作。
不幸的是,对于返回大量信息的进程,似乎在上一个OutputDataReceived
事件之前触发了Exited事件。
我怎么知道什么时候接收到最后一个" OutputDataReceived"?理想情况下,我希望"退出"事件是我收到的最后一个事件。
这是一个示例程序:
using System; using System.Diagnostics; using System.Threading; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { string command = "output.exe"; string arguments = " whatever"; ProcessStartInfo info = new ProcessStartInfo(command, arguments); // Redirect the standard output of the process. info.RedirectStandardOutput = true; info.RedirectStandardError = true; // Set UseShellExecute to false for redirection info.UseShellExecute = false; Process proc = new Process(); proc.StartInfo = info; proc.EnableRaisingEvents = true; // Set our event handler to asynchronously read the sort output. proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived); proc.ErrorDataReceived += new DataReceivedEventHandler(proc_ErrorDataReceived); proc.Exited += new EventHandler(proc_Exited); proc.Start(); // Start the asynchronous read of the sort output stream. Note this line! proc.BeginOutputReadLine(); proc.BeginErrorReadLine(); proc.WaitForExit(); Console.WriteLine("Exited (Main)"); } static void proc_Exited(object sender, EventArgs e) { Console.WriteLine("Exited (Event)"); } static void proc_ErrorDataReceived(object sender, DataReceivedEventArgs e) { Console.WriteLine("Error: {0}", e.Data); } static void proc_OutputDataReceived(object sender, DataReceivedEventArgs e) { Console.WriteLine("Output data: {0}", e.Data); } } }
运行该程序时,我们会注意到" Exited(Event)"(退出(事件))出现在输出中完全可变的位置。我们可能需要运行几次,并且很明显,我们将需要用自己选择的程序来替换" output.exe",该程序会产生大量的输出。
那么,问题又来了:我怎么知道什么时候接收到最后一个OutputDataReceived
?理想情况下,我希望"退出"事件是我收到的最后一个事件。
解决方案
回答
答案是将e.Data设置为null:
static void proc_ErrorDataReceived(object sender, DataReceivedEventArgs e) { if( e.Data == null ) _exited.Set(); }