Следует ли вызвать Dispose для Process.GetCurrentProcess()?

Например, см.

Как получить текущий ProcessID?

Никто не беспокоился о вызове Dispose для объекта, возвращаемого System.Diagnostics.Process.GetCurrentProcess(). Должно ли это называться? Пожалуйста, объясните, почему.

Ответ 1

Да, и на самом деле это тоже важно. Если вы видите фактический source, вы увидите, что Dispose не просто унаследован от Component, он тоже что-то делает.

Мне кажется, глядя на этот код, это наиболее важно, когда EnableRaisingEvents установлен в true, поскольку это связано с созданием дескриптора ожидания. Этот дескриптор должен быть выпущен для предотвращения утечки памяти и обработки.

Ответ 2

Это жесткий вызов.

Возможно, вам не придется вызывать 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.