我有一些System.Diagnotics.Processes要运行.我想自动调用close方法.显然,"using"关键字为我做了这个.
这是使用using关键字的方式吗?
foreach(string command in S) // command is something like "c:\a.exe" { try { using(p = Process.Start(command)) { // I literally put nothing in here. } } catch (Exception e) { // notify of process failure } }
我想开始多个进程同时运行.
using(p = Process.Start(command))
这将在Process
类实现时编译,IDisposable
但是您实际上想要调用该Close
方法.
逻辑会有这个Dispose
方法会Close
为你调用,并且通过使用反射器挖掘CLR,我们可以看到它确实为我们做了这个.到现在为止还挺好.
再次使用反射器,我查看了该Close
方法的作用 - 它释放了底层的本机win32进程句柄,并清除了一些成员变量.这(释放外部资源)正是 IDisposable模式应该做的事情.
但是我不确定这是否是你想要在这里实现的.
释放底层句柄只是对windows说'我不再对跟踪这个其他过程感兴趣了'.它决不会导致其他进程退出,或导致进程等待.
如果你想强制它们退出,你需要p.Kill()
在进程上使用该方法 - 但是请注意,杀死进程永远不是一个好主意,因为它们不能自行清理,并且可能会留下损坏的文件,并且等等.
如果你想等待他们自己退出,你可以使用p.WaitForExit()
- 但是这只有在你一次等待一个进程时才有效.如果你想同时等待它们,那就太棘手了.
通常你会使用WaitHandle.WaitAll
它,但由于没有办法从a中获取一个WaitHandle
对象System.Diagnostics.Process
,你不能这样做(严重来说,wtf是微软思考的吗?).
你可以为每个进程启动一个线程,并在那些线程中调用`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 }