应该调用Dispose for Process.GetCurrentProcess()吗?

时间:2015-01-19 11:22:06

标签: c# .net idisposable

例如,请参阅

How to get the current ProcessID?

没有人打扰为System.Diagnostics.Process.GetCurrentProcess()返回的对象调用Dispose。它应该被称为吗?请解释原因。

2 个答案:

答案 0 :(得分:4)

是的,实际上它也很重要。如果您看到实际的source,则会看到Dispose仅仅是从Component继承而来,它也会做一些事情。

在我看来,在查看代码时,EnableRaisingEvents设置为true时最重要,因为这涉及创建等待句柄。需要释放该句柄以防止记忆和处理泄漏。

答案 1 :(得分:1)

那真是个艰难的决定。

对于您从Dispose获得的Process实例,您可能不必致电Process.GetCurrentProcess(),以防您未触摸Handle属性以及其他一些敏感信息点。

让我们看看包含Process.Close逻辑实质的Dispose方法。

    public void Close()
    {
        if (this.Associated)
        {
            if (this.haveProcessHandle)
            {
                this.StopWatchingForExit();
                this.m_processHandle.Close();
                this.m_processHandle = null;
                this.haveProcessHandle = false;
            }
            this.haveProcessId = false;
            this.isRemoteMachine = false;
            this.machineName = ".";
            this.raisedOnExited = false;
            this.standardOutput = null;
            this.standardInput = null;
            this.standardError = null;
            this.Refresh();
        }
    }

仅在Process实例具有进程句柄的情况下,您才可以看到此处确实发生了某些事情。 Refresh方法与主题无关。

如果进一步看,您将看到访问Process属性时,Handle实例可以获取(并保持)进程句柄。这不是唯一的情况

    public IntPtr Handle
    {
        get
        {
            this.EnsureState(Process.State.Associated);
            return this.OpenProcessHandle().DangerousGetHandle();
        }
    }

作为一般规则:如果它实现IDisposable-您应该调用Dispose

在特定情况下,如果您仅触摸当前进程名称或无辜的名称,则可以忽略Dispose呼叫并取消它。

这里是一个例子:

        Process process = Process.GetCurrentProcess();

        var fieldInfo = typeof(Process).GetField("haveProcessHandle", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        var v1 = fieldInfo.GetValue(process);
        //v1 is false. Explicit Dispose is not necessary.

        var processName = process.ProcessName;
        var v2 = fieldInfo.GetValue(process);
        //v2 is false. Explicit Dispose is not necessary.

        var processHandle = process.Handle;
        var v3 = fieldInfo.GetValue(process);
        //v3 is true. Bah. Explicit Dispose IS necessary from now on.

我使用反射的唯一原因是:如果您通过Visual Studio调试器监视process变量,它将遍历属性并读取可怕的Handle属性。

Process类是“不良设计模式”的完美示例,因为它会极大地改变get访问器中的对象状态。