这是一个艰难的决定。
如果您没有触摸Handle 属性以及其他一些敏感点,您可能不必为从Process.GetCurrentProcess() 获得的Process 实例调用Dispose。
让我们看一下包含Dispose逻辑精髓的Process.Close方法。
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 方法对我们的主题没有任何兴趣。
如果您进一步观察,您会发现当访问Handle 属性时,Process 实例可以获取(并因此持有)进程句柄。这不是唯一的情况!
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 访问器中的对象状态。