If you close the process by calling .CloseMainWindow() , moving the call to the try / catch block is the right thing.
Do it:
try { process.CloseMainWindow() } catch (InvalidOperationException) {
This is due to the fact that checking the properties of the process before closing the process creates a race condition: both checking the properties and calling .CloseMainWindow() participate in races to see which ones can finish first.
Consider this series of events:
- Process is running
- Your code calls
process.HasExited and gets false - The process ends independently, upon completion
- Since the second step returned
false , your code calls process.CloseMainWindow() and gets an InvalidOperationException: Process has exited, so the requested information is not available.
No amount of acceleration of your code, neither the use of locks, nor any other strategy can guarantee that the process will not exit after your if . There is always a race condition. Use try/catch instead.
If you need to keep track of whether a process has been started, you might want to wrap the process in its class. You can use the lock when the process starts and set the boolean flag to indicate that it was running.
class ProcessWrapper { public HasStarted; public ProcessWrapper(Process p, ProcessStartInfo psi) {
source share