例如,请参阅
How to get the current ProcessID?
没有人打扰为System.Diagnostics.Process.GetCurrentProcess()
返回的对象调用Dispose。它应该被称为吗?请解释原因。
答案 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访问器中的对象状态。