我如何知道最后一个 OutputDataReceived 何时到达?
我在针对 .Net Framework 3.5 的程序中有一个 System.Diagnostics.Process 对象,
我已重定向 StandardOutput
和 StandardError
管道,并且我正在从它们异步接收数据。 我还为 Exited 事件设置了一个事件处理程序。
一旦我调用 Process.Start(),我就想在等待事件引发的同时去做其他工作。
不幸的是,对于返回大量信息的进程,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.exe”替换为您选择的可产生适当大量输出的程序。
那么,问题又来了:我如何知道最后一个 OutputDataReceived
何时收到? 理想情况下,我希望 Exited
事件成为我收到的最后一个事件。
I have a System.Diagnostics.Process object in a program targeted at the .Net framework 3.5
I have redirected both StandardOutput
and StandardError
pipes and I'm receiving data from them asynchronously. I've also set an event handler for the Exited event.
Once I call Process.Start()
I want to go off and do other work whilst I wait for events to be raised.
Unfortunately it appears that, for a process which returns a large amount of information, the Exited event is fired before the last OutputDataReceived
event.
How do I know when the last OutputDataReceived
has been received? Ideally I would like the Exited
event to be the last event I receive.
Here is an example program:
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);
}
}
}
When running this program you will notice that "Exited (Event)" appears in a completely variable location within the output. You may need to run it a few times and, obviously, you will need to replace "output.exe" with a program of your choice that produces a suitably large amount of output.
So, the question again: How do I know when the last OutputDataReceived
has been received? Ideally I would like the Exited
event to be the last event I receive.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
答案是 < code>e.Data 将设置为
null
:The answer to this is that
e.Data
will be set tonull
:如果将 e.Data 设置为 null 会更舒服,但实际上该值将是一个空字符串。 请注意,第一个值也可以是空字符串。 真正的答案是,一旦您收到空字符串以外的某个值,然后查找下一个空字符串。 我正在使用 Visual Studio 2019。
It will be more comfortable if e.Data set to null, but actually, the value will be an empty string. Please note the first value also could be Empty string. The real answer is once you receive some value other than Empty string, then look for next Empty string. I am using Visual Studio 2019.