我怎么知道最后一个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();
}