using(p = Process.Start(command))
Esto compilará, como la clase implementa Process
IDisposable
, sin embargo en realidad se quiere llamar al método Close
.
Lógica quiere que el método Dispose
llame al Close
, y al profundizar en el CLR utilizando el reflector, podemos ver que de hecho lo hace por nosotros. Hasta aquí todo bien.
De nuevo, usando el reflector, miré lo que hace el método Close
- libera el identificador de proceso win32 nativo subyacente y borra algunas variables miembro. Esto (liberar recursos externos) es exactamente lo que se supone que el patrón IDisposable debe hacer.
Sin embargo No estoy seguro de si esto es lo que quiere lograr aquí.
Liberar los controles subyacentes simplemente dice a Windows 'Ya no estoy interesado en seguir este otro proceso'. En ningún momento, esto hace que el otro proceso se cierre o que el proceso espere.
Si desea forzarlos a dejar de fumar, necesitará usar el método p.Kill()
en los procesos; sin embargo, tenga en cuenta que nunca es una buena idea matar procesos ya que no pueden limpiarlos y pueden irse. detrás de archivos corruptos, etc.
Si desea esperar a que se retiren por su cuenta, puede usar p.WaitForExit()
; sin embargo, esto solo funcionará si está esperando un proceso a la vez. Si quieres esperar a todos al mismo tiempo, se vuelve complicado.
Normalmente tendrá que utilizar WaitHandle.WaitAll
para esto, pero ya que no hay manera de conseguir un objeto WaitHandle
cabo de un System.Diagnostics.Process
, no se puede hacer esto (en serio, wtf estaban pensando Microsoft?).
Puede girar un hilo para cada proceso y llamar a `WaitForExit en esos hilos, pero esta también es la manera incorrecta de hacerlo.
En su lugar, tiene que usar p/invoke para acceder a la función win12 WaitForMultipleObjects
nativa.
He aquí una muestra (que he probado y realmente funciona)
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
static extern uint WaitForMultipleObjects(uint nCount, IntPtr[] lpHandles, bool bWaitAll, uint dwMilliseconds);
static void Main(string[] args)
{
var procs = new Process[] {
Process.Start(@"C:\Program Files\ruby\bin\ruby.exe", "-e 'sleep 2'"),
Process.Start(@"C:\Program Files\ruby\bin\ruby.exe", "-e 'sleep 3'"),
Process.Start(@"C:\Program Files\ruby\bin\ruby.exe", "-e 'sleep 4'") };
// all started asynchronously in the background
var handles = procs.Select(p => p.Handle).ToArray();
WaitForMultipleObjects((uint)handles.Length, handles, true, uint.MaxValue); // uint.maxvalue waits forever
}