我有一些 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
方法的作用 - 它释放了底层的 native win32 进程句柄,并清除了一些成员变量。这(释放外部资源)正是 IDisposable 模式应该做的事情。
但是我不确定这是否是您想在这里实现的目标。
释放底层句柄只是对窗口说“我不再对跟踪这个其他进程感兴趣”。它实际上绝不会导致其他进程退出,或导致您的进程等待。
如果你想强制他们退出,你需要在进程上使用 p.Kill()
方法 - 但是请注意,杀死进程永远不是一个好主意,因为他们可以自行清理,可能会留下损坏的文件等。
如果你想等待它们自己退出,你可以使用 p.WaitForExit()
- 但是这只有在你一次等待一个进程时才有效。如果您想同时等待它们,那就很棘手了。
通常您会为此使用 WaitHandle.WaitAll
,但是因为没有办法从 System.Diagnostics.Process< 中获取
,你不能这样做(说真的,微软在想什么?)。WaitHandle
对象
您可以为每个进程启动一个线程,并在这些线程中调用 `WaitForExit,但这也是错误的做法。
您必须改为使用 p/invoke 来访问 native 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
}
关于c# - 如何以编程方式在 C# 中使用 "using"关键字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/185381/