process.WaitForExit () asincrónicamente

Quiero esperar a que termine un proceso, pero process.WaitForExit() cuelga mi GUI. ¿Hay alguna forma de evento, o necesito generar un hilo para bloquear hasta la salida, y luego delegar el evento yo mismo?

process.EnableRaisingEvents = true;
process.Exited + = [EventHandler]

A partir de .NET 4.0 / C # 5, es más agradable representar esto usando el patrón asíncrono.

 ///  /// Waits asynchronously for the process to exit. ///  /// The process to wait for cancellation. /// A cancellation token. If invoked, the task will return /// immediately as canceled. /// A Task representing waiting for the process to end. public static Task WaitForExitAsync(this Process process, CancellationToken cancellationToken = default(CancellationToken)) { var tcs = new TaskCompletionSource(); process.EnableRaisingEvents = true; process.Exited += (sender, args) => tcs.TrySetResult(null); if(cancellationToken != default(CancellationToken)) cancellationToken.Register(tcs.SetCanceled); return tcs.Task; } 

Uso:

 public async void Test() { var process = new Process("processName"); process.Start(); await process.WaitForExitAsync(); //Do some fun stuff here... } 

Si elige @MgSam answer, tenga en cuenta que si pasa por WaitForExitAsync algún CancellationToken , que se cancelará automáticamente después del retraso especificado, puede obtener una InvalidOperationException . Para arreglar eso, necesitas cambiar

 cancellationToken.Register(tcs.SetCanceled); 

a

 cancellationToken.Register( () => { tcs.TrySetCanceled(); } ); 

PD: no olvide desechar su CancellationTokenSource a tiempo.

De acuerdo con este enlace, el método WaitForExit () se utiliza para hacer que el hilo actual espere hasta que finalice el proceso asociado. Sin embargo, el Proceso tiene un evento Exited que puede enganchar.

Aquí hay un método de extensión que es un poco más limpio, porque limpia el registro de token de cancelación y el evento Salir. También maneja el caso de borde de condición de carrera, donde el proceso podría finalizar después de que comenzó, pero antes de que se adjuntara el evento Exited. Utiliza la nueva syntax de funciones locales en C # 7.

 public static class ProcessExtensions { public static async Task WaitForExitAsync(this Process process, CancellationToken cancellationToken = default) { var tcs = new TaskCompletionSource(); void Process_Exited(object sender, EventArgs e) { tcs.TrySetResult(true); } process.EnableRaisingEvents = true; process.Exited += Process_Exited; try { if (process.HasExited) { return; } using (cancellationToken.Register(() => tcs.TrySetCanceled())) { await tcs.Task; } } finally { process.Exited -= Process_Exited; } } } 

Use System.Diagnostics.Process.Exited