2008-09-15 12 views
18

J'ai un objet System.Diagnostics.Process dans un programme ciblé sur le cadre 3.5Comment savoir quand le dernier OutputDataReceived est arrivé?

.Net

Je redirigée les StandardOutput et StandardError tuyaux et je reçois d'eux des données de manière asynchrone. J'ai également défini un gestionnaire d'événement pour l'événement Exited.

Une fois que j'appelle Process.Start() Je veux partir et faire d'autres travaux pendant que j'attends que les événements soient augmentés.

Malheureusement, il semble que, pour un processus qui renvoie une grande quantité d'informations, l'événement Exited est déclenché avant le dernier événement OutputDataReceived.

Comment savoir quand le dernier OutputDataReceived a été reçu? Idéalement, j'aimerais que l'événement Exited soit le dernier événement que je reçois.

Voici un exemple de programme:

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); 
    } 


    } 
} 

Lors de l'exécution de ce programme, vous remarquerez que « Exited (Event) » apparaît dans un endroit tout à fait variable dans la sortie. Vous devrez peut-être l'exécuter plusieurs fois et, évidemment, vous devrez remplacer "output.exe" par un programme de votre choix qui produit une quantité suffisante de sortie.

Donc, la question encore une fois: Comment puis-je savoir quand le dernier OutputDataReceived a été reçu? Idéalement, j'aimerais que l'événement Exited soit le dernier événement que je reçois.

Répondre

23

La réponse à cela est que e.Data will be set to null:

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