¿Por qué no se llama al método Exited de mi proceso?

96

Tengo el siguiente código, pero ¿por qué ProcessExitednunca se llama al método? Es lo mismo si no uso el shell de 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
}
5 años más tardeDBA
fuente

Respuestas:

241

Para recibir una devolución de llamada en Exitedcaso de evento, EnableRaisingEventsdebe establecerse en verdadero.

Process correctionProcess = Process.Start(startInfo);
correctionProcess.EnableRaisingEvents = true;
correctionProcess.Exited += new EventHandler(ProcessExited); 
Elíseo
fuente
3
correctProcess.WaitForSalir (), sin esta función este código no me funciona
Kira
7
Un pequeño consejo (especialmente para los que no son expertos en C #): ¡no Close()el proceso! Me he encontrado con un problema intermitente con el controlador de salida debido a un esfuerzo equivocado en la gestión de recursos. El código en cuestión se llama Process.Close()después Process.Start(startInfo), en lugar de permitir que el GC lo recopile a su debido tiempo. Error fácil si su experiencia es lenguajes que no son de GC (por ejemplo, C / C ++).
Jerzy
3
Excelente. Gracias. También quiero señalar que la asignación de EnableRaisingEventsy EventHandlersdebe realizarse exactamente después del Process.Start(). De lo contrario, no funcionará.
Doruk
2
@Doruk Puedo configurar EnableRaisingEvents=trueantes de llamar Process.Start()y funciona bien.
Acción Dan
29

Desde MSDN :

El evento Exited indica que el proceso asociado salió. Esta ocurrencia significa que el proceso terminó (abortó) o se cerró con éxito. Este evento solo puede ocurrir si el valor de la propiedad EnableRaisingEvents es verdadero.

¿Ha establecido esa propiedad en verdadera?

CodificaciónGorilla
fuente
19
También es una bandera muy poco idomática (de qué sirve de todos modos, si no quiero el evento, ¡no me suscribo!)
Tamás Szelei
3
No muy intuitivo. Debe indicar claramente en la descripción de cada evento que requiere que se establezca esta bandera.
TheLegendaryCopyCoder
18

Debe establecer Process.EnableRaisingEventsa true.

Sam B
fuente
13

Establecer correcciónProcess.EnableRaisingEvents = true

Gary L Cox Jr
fuente
9

Me he encontrado con ejemplos que se colocan new Process()en una usingcláusula. No hagas eso si quieres usar la Exitedfunción. La usingcláusula destruye la instancia junto con los controladores de eventos Exited.

Esta...

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

Debería ser esto ...

var process = new Process();
Adam Cox
fuente
Yo también lo he notado. Curiosamente, los eventos OutputDataReceived funcionan bien. O pueden ocurrir tan rápido que van antes de que la ejecución en el hilo principal llegue a End Using.
AlexVB