[英]How do I know when the last OutputDataReceived has arrived?
我在一个针对.Net framework 3.5的程序中有一个System.Diagnostics.Process object
我已经重定向了StandardOutput
和StandardError
管道,并且我正在从它们异步接收数据。 我还为 Exited 事件设置了一个事件处理程序。
调用Process.Start()
后,我想关闭 go 并在等待引发事件的同时做其他工作。
不幸的是,对于返回大量信息的进程,Exited 事件似乎在最后一个OutputDataReceived
事件之前被触发。
我如何知道收到最后一个OutputDataReceived
的时间? 理想情况下,我希望Exited
事件成为我收到的最后一个事件。
这是一个示例程序:
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 内的一个完全可变的位置。 您可能需要运行它几次,显然,您需要将“output.exe”替换为您选择的程序,该程序会产生大量的 output。
所以,问题又来了:我怎么知道最后一个OutputDataReceived
是什么时候收到的? 理想情况下,我希望Exited
事件成为我收到的最后一个事件。
答案是e.Data
将设置为null
:
static void proc_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
if( e.Data == null ) _exited.Set();
}
如果 e.Data 设置为 null 会更舒服,但实际上,该值将是一个空字符串。 请注意,第一个值也可以是空字符串。 真正的答案是,一旦您收到空字符串以外的其他值,然后查找下一个空字符串。 我正在使用 Visual Studio 2019。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.