【问题标题】:If I kill a System.Diagnostics.Process with .Kill(), do I also need to call .Close()?如果我用 .Kill() 杀死 System.Diagnostics.Process,是否还需要调用 .Close()?
【发布时间】:2011-08-04 07:39:00
【问题描述】:

使用 C# 4.0,我创建了一个 System.Diagnostics.Process,我希望它需要很短的时间来运行。如果由于某种原因该进程在一段时间后没有退出(例如,我调用了.WaitForExit(timeout),返回值为false),我需要清理。我决定在这种特殊情况下使用.Kill() 是安全的(没有我担心损坏的数据结构)。

鉴于此设置,我是否还需要调用 Process 的 .Close() 方法?如果是这样,我应该在.Kill() 之前还是之后打电话给.Close()

【问题讨论】:

标签: c# .net process kill


【解决方案1】:

System.Diagnostics.Process 通过Component 类实现IDisposable,受保护的Dispose(bool) 方法调用Close()。通常认为在使用完一次性资源后处理它们是一种好的做法,因为这将立即释放与该类关联的所有资源(不必等待 GC 运行)。

所以回答你的问题:

是的,请通过直接调用Dispose() 方法或通过C# using 构造调用Close(),如下所示。

using(Process proc = CreateProcess())
{
    StartProcess(proc);
    if (!proc.WaitForExit(timeout))
    {
        proc.Kill();
    }
}

【讨论】:

  • 尽管 Close() 在这里并不那么重要,因为 Kill() 会清理内部的非托管资源,为 using 块 +1。
  • 请重新表述您关于一次性用品的声明 - GC 和 IDisposable 之间没有直接关系。如果您调用 dispose,则该类应释放 GC 无论如何都无法清理的所有非托管资源。如果您释放任何托管资源(例如终止对它们的引用),那么这仍然不会影响 GC 运行的时间和方式。
  • @ChrisWue:你是对的,但是我不想深入探讨 Disposable Pattern 的实现细节。当模式正确实现时,类终结器还将调用Dispose() 并清理任何尚未释放的本机资源。在这种情况下,GC 正在调用终结器,触发 Dispose() 调用。
  • 我不能在这个特定的上下文中使用 using 块,但可以接受指出该进程是 IDisposable(我没有注意到!)。谢谢!
  • 此答案中的代码包含竞争条件stackoverflow.com/q/13564645/57428
【解决方案2】:

Process.Kill()Process.Close() 都在与进程关联的私有 SafeProcessHandle 对象上内部调用 Close()。但是,Process.Close() 还明确重置了其他几个内部成员。

由于 Process 实现了IDisposable,因此您应该始终在完成后调用Close(),或者将其包装在using 块中。

【讨论】:

    猜你喜欢
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 2011-04-11
    • 2017-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多