Как мне узнать, когда прибыл последний OutputDataReceived? - PullRequest
20 голосов
/ 15 сентября 2008

У меня есть объект System.Diagnostics.Process в программе, нацеленной на .Net framework 3.5

Я перенаправил каналы 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 было последним полученным событием.

1 Ответ

26 голосов
/ 15 сентября 2009

Ответ на этот вопрос таков: e.Data будет установлен на null:

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