20

Using C# 4.0, I've created a System.Diagnostics.Process that I expect to take a short amount of time to run. If for some reason the process hasn't exited after some amount of time (e.g, I've called .WaitForExit(timeout) and the return value was false), I need to cleanup. I've decided that it's safe to use .Kill() in this particular situation (there are no data structures I'm worried about corrupting).

Given this setup, do I also need to call the .Close() method of the Process? If so, should I call .Close() before or after .Kill()?

Chris Phillips
  • 11,607
  • 3
  • 34
  • 45
  • from here http://stackoverflow.com/questions/673031/process-close-is-not-terminating-created-process-c `Close` won't abort the actual process, but your view of it and its associated resources. – Simon Fox Apr 13 '11 at 00:27

2 Answers2

13

System.Diagnostics.Process implements IDisposable via the Component class, and the protected Dispose(bool) method calls Close(). It is generally considered good practice to dispose of disposable resources when you are done with them, as this will immediately release any resources associated with the class (not having to wait for the GC to run).

So to answer your question:

Yes, please call Close() by calling the Dispose() method directly or via the C# using construct as follows.

using(Process proc = CreateProcess())
{
    StartProcess(proc);
    if (!proc.WaitForExit(timeout))
    {
        proc.Kill();
    }
}
Steve Guidi
  • 19,700
  • 9
  • 74
  • 90
  • 2
    Even though Close() isn't really that important here, because Kill() will clean up the internal unmanaged resources, +1 for the using block. – R. Martinho Fernandes Apr 13 '11 at 00:09
  • 3
    Please rephrase your statement about the disposable - there is no immediate relationship between GC and `IDisposable`. If you call dispose then the class should release all unmanaged resources which the GC cannot cleanup anyway. If you release any managed resource (like killing the reference to them) then this will still have no effect when and how the GC runs. – ChrisWue Apr 13 '11 at 00:38
  • @ChrisWue: You are correct, however I didn't want to get into the implementation details of the Disposable Pattern. When the pattern is implemented correctly, the class finalizer will also call `Dispose()` and clean up any native resources not already released. In this case, the GC is calling the finalizer, triggering the `Dispose()` call. – Steve Guidi Apr 13 '11 at 00:48
  • I can't use a using block in this particular context, but accepted for pointing out that process is IDisposable (I hadn't noticed!). Thanks! – Chris Phillips Apr 14 '11 at 04:02
  • The code in this answer contains a race condition http://stackoverflow.com/q/13564645/57428 – sharptooth Jan 21 '14 at 04:45
12

Process.Kill() and Process.Close() both internally call Close() on the private SafeProcessHandle object associated with the process. However, Process.Close() also explicitly resets several other internal members.

Since Process implements IDisposable, you should always call Close() on it when you are done, or wrap it in a using block.

Kevin Babcock
  • 10,187
  • 19
  • 69
  • 89