Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should one call Dispose for Process.GetCurrentProcess()?

For example, see

How to get the current ProcessID?

No one bothered to call Dispose for an object returned by System.Diagnostics.Process.GetCurrentProcess(). Should it actually be called? Please explain why.

like image 356
Ivan Ivanov Avatar asked Jan 19 '15 11:01

Ivan Ivanov


People also ask

When should you call Dispose?

Rule of thumb: if a class implements IDisposable you should always call the Dispose method as soon as you have finished using this resource. Even better wrap it in a using statement to ensure that the Dispose method will be called even if an exception is thrown: using (var reader = conn. ExecuteReader()) { ... }

Do you need to call Dispose?

If you are using a class that implements the IDisposable interface, you should call its Dispose implementation when you are finished using the class.

Can we call Dispose method in C#?

The Dispose Method—Explicit Resource Cleanup Unlike Finalize, developers should call Dispose explicitly to free unmanaged resources. In fact, you should call the Dispose method explicitly on any object that implements it to free any unmanaged resources for which the object may be holding references.


2 Answers

Yes, and actually it is important too. If you see the actual source, you will see the Dispose isn't just inherited from Component, it does something too.

It seems to me, looking at that code, that it is most important when EnableRaisingEvents is set to true, since that involves creating a wait handle. That handle needs to be released in order to prevent memory and handle leaking.

like image 59
Patrick Hofman Avatar answered Oct 18 '22 19:10

Patrick Hofman


That`s a tough call.

You may not have to call Dispose for the Process instance you got from the Process.GetCurrentProcess() in case you did not touch the Handle property as well as some other sensitive spots.

Lets have a look at the Process.Close method which contains the essence of Dispose logic.

    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();
        }
    }

You can see that something real occurs here only if the Process instance has a process handle. Refresh method has nothing of interest for our topic.

If you look further, you will see that the process handle can be obtained (and thus held) by the Process instance when the Handle property is accessed. This is not the only case though!

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

As a generic rule: if it implements IDisposable - you ought to call Dispose.

In your specific case, if you only touch the current process name or something as innocent, you can omit the Dispose call and get away with it.

Here is an example:

        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.

I use the reflection for one sole reason: if you monitor the process variable via Visual Studio debugger, it is going to walk through the properties and read the dreaded Handle property.

Process class is a perfect example of a "bad design pattern" as it drastically changes the object state in a get accessor.

like image 30
Zverev Evgeniy Avatar answered Oct 18 '22 20:10

Zverev Evgeniy