我如何知道最后一个 OutputDataReceived 何时到达?

发布于 2024-07-04 12:00:39 字数 2290 浏览 10 评论 0原文

我在针对 .Net Framework 3.5 的程序中有一个 System.Diagnostics.Process 对象,

我已重定向 StandardOutputStandardError 管道,并且我正在从它们异步接收数据。 我还为 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无所谓啦 2024-07-11 12:00:39

答案是 < code>e.Data 将设置为 null

static void proc_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
     if( e.Data == null ) _exited.Set();
}

The answer to this is that e.Data will be set to null:

static void proc_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
     if( e.Data == null ) _exited.Set();
}
長街聽風 2024-07-11 12:00:39

如果将 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文