Perché il metodo Exited del mio processo non viene chiamato?


96

Ho il seguente codice, ma perché il ProcessExitedmetodo non viene mai chiamato? È lo stesso se non uso la shell di Windows ( startInfo.UseShellExecute = false).

ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = path;
startInfo.Arguments = rawDataFileName;
startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1);

try
{
     Process correctionProcess = Process.Start(startInfo);
     correctionProcess.Exited += new EventHandler(ProcessExited);                   

     correctionProcess.WaitForExit();

     status = true;
}

.....

internal void ProcessExited(object sender, System.EventArgs e)
{
      //print out here
}

Risposte:


241

Per ricevere una richiamata su Exitedevento, il EnableRaisingEventsdeve essere impostato su true.

Process correctionProcess = Process.Start(startInfo);
correctionProcess.EnableRaisingEvents = true;
correctionProcess.Exited += new EventHandler(ProcessExited); 

3
correctionProcess.WaitForExit (), senza questa funzione questo codice non funziona per me
Kira

7
Un piccolo consiglio (specialmente per gli esperti non C #): non Close()il processo! Ho riscontrato un problema intermittente con il gestore di uscita a causa di uno sforzo errato nella gestione delle risorse. Il codice in questione ha chiamato Process.Close()dopo Process.Start(startInfo), piuttosto che permettere il GC di raccogliere a tempo debito. Facile errore se il tuo background non è un linguaggio GC (ad esempio C / C ++).
Jerzy

3
Grande. Grazie. Voglio anche sottolineare che l'assegnazione di EnableRaisingEventse EventHandlersdeve essere eseguita esattamente dopo Process.Start(). Altrimenti non funzionerà.
Doruk

2
@ Doruk posso impostare EnableRaisingEvents=trueprima di chiamare Process.Start()e funziona bene.
Azione Dan

29

Da MSDN :

L'evento Exited indica che il processo associato è terminato. Questa occorrenza significa che il processo è terminato (interrotto) o chiuso con successo. Questo evento può verificarsi solo se il valore della proprietà EnableRaisingEvents è true.

Hai impostato quella proprietà su true?


19
È anche una bandiera molto poco idomatica (a che serve comunque, se non voglio l'evento, non mi iscrivo!)
Tamás Szelei

3
Non molto intuitivo. Deve indicare chiaramente nella descrizione di ogni evento che richiede l'impostazione di questo flag.
TheLegendaryCopyCoder

18

È necessario impostare Process.EnableRaisingEventsa true.



9

Mi sono imbattuto in esempi che collocano new Process()in una usingclausola. Non farlo se desideri utilizzare la Exitedfunzione. La usingclausola distrugge l'istanza insieme a qualsiasi handle di evento Exited.

Questo...

using(var process = new Process())
{
   // your logic here
}

Dovrebbe essere questo ...

var process = new Process();

L'ho notato anche io. Stranamente, gli eventi OutputDataReceived funzionano bene. O possono essere così veloci che vanno prima che l'esecuzione nel thread principale arrivi a End Using.
AlexVB
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.