c# - 如何以编程方式在 C# 中使用 "using"关键字?

标签 c# process

我有一些 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/

相关文章:

c# - 我应该如何清除通用静态类中的字段?

c# - 来自 Windows Store 应用程序的 Windows Azure 存储 REST API 的授权 header

objective-c - 无法在 Cocoa 中找到正在运行的应用程序

linux - pcpu 表示什么以及为什么乘以 1000?

将基于进程的程序转换为基于线程的版本?

c - 是否可以仅按名称管理 JobObject,而无需保持打开的 HANDLE?

c# - 无效操作异常 : Record reader index out of sync

c# - 以 XML 形式获取 WCF web 服务响应

C# WPF 迭代子项和更改属性的更好方法

python - 在 Linux 中创建两个进程并获取输出