Например, см.
Как получить текущий ProcessID?
Никто не беспокоился о вызове Dispose для объекта, возвращаемого System.Diagnostics.Process.GetCurrentProcess()
. Должно ли это называться? Пожалуйста, объясните, почему.
Например, см.
Как получить текущий ProcessID?
Никто не беспокоился о вызове Dispose для объекта, возвращаемого System.Diagnostics.Process.GetCurrentProcess()
. Должно ли это называться? Пожалуйста, объясните, почему.
Да, и на самом деле это тоже важно. Если вы видите фактический source, вы увидите, что Dispose
не просто унаследован от Component
, он тоже что-то делает.
Мне кажется, глядя на этот код, это наиболее важно, когда EnableRaisingEvents
установлен в true
, поскольку это связано с созданием дескриптора ожидания. Этот дескриптор должен быть выпущен для предотвращения утечки памяти и обработки.
Это жесткий вызов.
Возможно, вам не придется вызывать 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.
Я использую отражение по одной единственной причине: если вы отслеживаете переменную process
через отладчик Visual Studio, она собирается просмотреть свойства и прочитать страшное свойство Handle
.
Класс Process
является прекрасным примером "плохого шаблона проектирования", так как он резко меняет состояние объекта в методе доступа get.