title: .NET Process.Kill() in a safe way
body: <p>I'm controlling a creaky old FORTRAN simulator from a VB.NET GUI, using redirected I/O to communicate with the simulator executable. The GUI pops up a "status" window with a progress bar, estimated time, and a "STOP" button (<code>Button_Stop</code>).</p>
  
  <p>Now, I want the <code>Button_Stop</code> to terminate the simulator process immediately. The obvious way to do this is to call <code>Kill()</code> on the <code>Child</code> Process object. This gives an exception if it's done after the process has exited, but I can test whether the process is exited before trying to kill it, right?</p>
  
  <p>OK, so I do the following when the button is clicked:</p>
  
  <pre><code>If Not Child.HasExited Then
      Child.Kill()
      Button_Stop.Enabled = False
  End If
  </code></pre>
  
  <p>However, what if the process happens to exit between the test and the call to <code>Kill()</code>? In that case, I get an exception.</p>
  
  <p>The next thing to occur to me was that I can do <code>Button_Stop.Enabled = False</code> in the <code>Process.Exited</code> event handler, and thus prevent the <code>Child.Kill()</code> call in the <code>Button_Stop.Clicked</code> handler. But since the <code>Process.Exited</code> handler is called on a different thread, that still leaves the following possible interleaving:</p>
  
  <ol>
  <li>Child process exits.</li>
  <li><code>Process.Exited</code> fires, calls <code>Invoke</code> to schedule the <code>Button_Stop.Enabled = False</code></li>
  <li>User clicks on <code>Button_Stop</code>, triggering <code>Child.Kill()</code></li>
  <li><code>Button_Stop.Enabled = False</code> actually happens.</li>
  </ol>
  
  <p>An exception would then be thrown on step 3.</p>
  
  <p>How do I kill the process without any race conditions? Am I thinking about this entirely wrong?</p>