4

I have an application that creates Process objects in order to launch external applications. Once it verifies the application has launched correctly, it no longer cares about it, so I don't need the Process object any longer, but I can't call Dispose() on it because I don't want to shutdown the process. What is the workaround for this?

amnesia
  • 1,956
  • 2
  • 18
  • 36
  • Why do you need to dispose of it? – D Stanley May 28 '15 at 14:54
  • 1
    @DStanley because it implements IDisposable. You always need to dispose those objects or you will leak handles or other unmanaged resources. – amnesia May 28 '15 at 15:05
  • 1
    @amnesia Are you sure it will kill the process? Have you tried it? – xanatos May 28 '15 at 15:06
  • 1
    @antiduh Sadly the duplicate response speaks only on "you really should dispose it" but doesn't say if it will kill the process :-) – xanatos May 28 '15 at 15:31
  • Voting to reopen. As @xanatos points out, the dupe target and its answers do not address the question of whether disposing the Process object will kill the process. – Blackwood Nov 18 '18 at 21:44

2 Answers2

12

You can safely Dispose the process instance, the process will run after.

class Program
{
    static void Main(string[] args)
    {
        Process p = new Process
        {
            StartInfo = {FileName = "notepad.exe"}
        };
        p.Start();

        p.Dispose();
        // Notepad still runs...
        GC.Collect(); // Just for the diagnostics....
        // Notepad still runs...
        Console.ReadKey();
    }
}

Actually the process (Notepad.exe) will even run after your .NET app was terminated. Btw that's one of the reason I recommend not to worry about the Process instances and disposing them before the process actually terminated: You will lost your control handle to stop the OS processes or query their status. Unless you have zillion of Process instances I should not worry about them.

g.pickardou
  • 32,346
  • 36
  • 123
  • 268
  • Wow, I'm an idiot, I just assumed without testing. Thanks for the proof. – amnesia May 28 '15 at 15:17
  • 1
    It is terrible advice to tell someone to not bother disposing something - it is disposable for a reason. The reason is that the `Process` object holds onto *machine wide* resources (process handles) while it is valid. `Process` implements a finalizer, and thus is immediately registered on the finalizer queue as soon as it is constructed; it remains on that queue unless you call `Dispose()`. It'll take a GC run to find out that the object is released, a finalizer run to run the finalizer and release those handles, and another GC run to reclaim the object's memory. **ALWAYS DISPOSE DISPOSABLES** – antiduh May 28 '15 at 15:18
  • For more information on exactly why you should dispose `Process` objects, refer to this answer: http://stackoverflow.com/questions/16957320/what-does-process-dispose-actually-do – antiduh May 28 '15 at 15:20
  • antiduh: You are completely right, I meant "recommend not to worry about the Process instances and disposing them before the process actually terminated". I've edited my answer – g.pickardou May 28 '15 at 15:28
1

I think that Process.Close() and Process.Dispose() don't kill the process. They simply release some resources connected to handling the process.

From the reference source:

protected override void Dispose(bool disposing) {
    if( !disposed) {
        if (disposing) {
            //Dispose managed and unmanaged resources
            Close();
        }
        this.disposed = true;
        base.Dispose(disposing);                
    }            
}

and

public void Close() {
    if (Associated) {
        if (haveProcessHandle) {
            StopWatchingForExit();
            Debug.WriteLineIf(processTracing.TraceVerbose, "Process - CloseHandle(process) in Close()");
            m_processHandle.Close();
            m_processHandle = null;
            haveProcessHandle = false;
        }
        haveProcessId = false;
        isRemoteMachine = false;
        machineName = ".";
        raisedOnExited = false;

        //Don't call close on the Readers and writers
        //since they might be referenced by somebody else while the 
        //process is still alive but this method called.
        standardOutput = null;
        standardInput = null;
        standardError = null;

        output = null;
        error = null;

        Refresh();
    }
}

I don't see anything that should kill the process.

xanatos
  • 109,618
  • 12
  • 197
  • 280
  • You are right in the final conclusion, however the source does not proves it: We do not see what is going in in the base.Dispose(disposing); – g.pickardou May 28 '15 at 15:15
  • @g.pickardou But I have :-) The base class is a `Component`, and its `Dispose` does some `Component` cleaning. And in the end, after the `this.m_processHandle.Close();` the `Process` (class) can't anymore control the process, because that is its Windows `HANDLE` to the process. – xanatos May 28 '15 at 15:17
  • I believe you saw it, I've just mentioned that the provided sample does not prove it. – g.pickardou May 28 '15 at 15:27