using(p = Process.Start(command))
Это скомпилируется, поскольку класс Process
реализует IDisposable
, однако вы действительно хотите вызвать метод Close
.
Логика будет иметь то, что метод Dispose
будет вызывать для вас Close
, и, копаясь в CLR с помощью рефлектора, мы видим, что он действительно делает это для нас. Пока все хорошо.
Снова используя отражатель, я посмотрел, что делает метод Close
- он освобождает основной дескриптор процесса win32 и очищает некоторые переменные-члены. Это (высвобождение внешних ресурсов) точно , что должен делать шаблон IDisposable.
Однако Я не уверен, что это то, чего вы хотите достичь здесь.
Выпуск базовых дескрипторов просто говорит окнам: «Я больше не заинтересован в отслеживании этого другого процесса». Это ни в коем случае не приводит к тому, что другой процесс завершает работу, и не заставляет ваш процесс ждать.
Если вы хотите принудительно завершить их, вам нужно использовать метод p.Kill()
для процессов - однако имейте в виду, что убивать процессы никогда не будет хорошей идеей, поскольку они не могут очистить себя, и могут оставить поврежденные файлы и т. д.
Если вы хотите подождать, пока они выйдут самостоятельно, вы можете использовать p.WaitForExit()
- однако это будет работать, только если вы ожидаете один процесс за раз. Если вы хотите дождаться их всех одновременно, это будет сложно.
Обычно вы бы использовали WaitHandle.WaitAll
для этого, но, поскольку нет никакого способа получить WaitHandle
объект из System.Diagnostics.Process
, вы не можете этого сделать (серьезно, если бы Майкрософт подумал?).
Вы можете раскрутить поток для каждого процесса и вызвать `WaitForExit в этих потоках, но это также неправильный способ сделать это.
Вместо этого вам нужно использовать p / invoke для доступа к собственной функции win32 WaitForMultipleObjects
.
Вот пример (который я тестировал и на самом деле работает)
[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
}