Comienza el proceso asincrónico y espera a que termine

Soy nuevo en el modelo de subprocesos en .net. ¿Qué usarías para:

  1. iniciar un proceso que maneja un archivo (process.StartInfo.FileName = fileName;)
  2. esperar a que el usuario cierre el proceso O abandonar el hilo después de un tiempo
  3. si el usuario cerró el proceso, elimine el archivo

El inicio del proceso y la espera deben realizarse en un hilo diferente al del hilo principal, ya que esta operación no debería afectar a la aplicación.

Ejemplo:

Mi aplicación produce un informe html. El usuario puede hacer clic derecho en cualquier parte y decir “Ver informe”: ahora recupero los contenidos del informe en un archivo temporal y ejecuto el proceso que maneja los archivos html, es decir, el navegador predeterminado. El problema es que no puedo limpiar, es decir, eliminar el archivo temporal.

“y esperar debe ser asincrónico” – No bash ser gracioso, pero ¿no es eso una contradicción en los términos? Sin embargo, dado que está iniciando un Process , el evento Exited puede ayudar:

 ProcessStartInfo startInfo = null; Process process = Process.Start(startInfo); process.EnableRaisingEvents = true; process.Exited += delegate {/* clean up*/}; 

Si realmente quiere esperar (tiempo de espera, etc.), entonces:

 if(process.WaitForExit(timeout)) { // user exited } else { // timeout (perhaps process.Kill();) } 

Para esperar la sincronización, ¿tal vez solo use un hilo diferente?

 ThreadPool.QueueUserWorkItem(delegate { Process process = Process.Start(startInfo); if(process.WaitForExit(timeout)) { // user exited } else { // timeout } }); 

Agregar una alternativa avanzada a esta vieja pregunta. Si desea esperar a que un proceso salga sin bloquear ningún hilo y todavía admite tiempos de espera, intente lo siguiente:

  public static Task WaitForExitAsync(this Process process, TimeSpan timeout) { ManualResetEvent processWaitObject = new ManualResetEvent(false); processWaitObject.SafeWaitHandle = new SafeWaitHandle(process.Handle, false); TaskCompletionSource tcs = new TaskCompletionSource(); RegisteredWaitHandle registeredProcessWaitHandle = null; registeredProcessWaitHandle = ThreadPool.RegisterWaitForSingleObject( processWaitObject, delegate(object state, bool timedOut) { if (!timedOut) { registeredProcessWaitHandle.Unregister(null); } processWaitObject.Dispose(); tcs.SetResult(!timedOut); }, null /* state */, timeout, true /* executeOnlyOnce */); return tcs.Task; } 

De nuevo, la ventaja de este enfoque en comparación con la respuesta aceptada es que no está bloqueando ningún subproceso, lo que reduce la sobrecarga de su aplicación.

Pruebe el siguiente código.

 public void KickOffProcess(string filePath) { var proc = Process.Start(filePath); ThreadPool.QueueUserWorkItem(new WaitCallBack(WaitForProc), proc); } private void WaitForProc(object obj) { var proc = (Process)obj; proc.WaitForExit(); // Do the file deletion here } 

Probablemente no use un proceso separado para abrir un archivo. En cambio, probablemente utilizaría un hilo de fondo (si pensé que la operación iba a llevar mucho tiempo y posiblemente bloquearía el hilo de UI).

 private delegate void FileOpenDelegate(string filename); public void OpenFile(string filename) { FileOpenDelegate fileOpenDelegate = OpenFileAsync; AsyncCallback callback = AsyncCompleteMethod; fileOpenDelegate.BeginInvoke(filename, callback, state); } private void OpenFileAsync(string filename) { // file opening code here, and then do whatever with the file } 

Por supuesto, este no es un buen ejemplo de trabajo (no devuelve nada) y no he mostrado cómo se actualiza la UI (tienes que usar BeginInvoke en el nivel de UI porque un hilo de fondo no puede actualizar el hilo de UI). Pero, en general, este enfoque es el manejo de las operaciones asincrónicas en .Net.

Puede usar el evento Exited en la clase Process

 ProcessStartInfo info = new ProcessStartInfo(); info.FileName = "notepad.exe"; Process process = Process.Start(info); process.Exited += new EventHandler(process_Exited); Console.Read(); 

y en ese caso puedes manejar las operaciones que mencionaste