[Process] Do not use Exited as it's racy with Start and BeginOutputReadLine/BeginErrorReadLine
The issue can arise if the Process is going to run faster than the call
between Start and BeginOutputReadLine/BeginErrorReadLine. To increase
the chance of the race happening, insert a Thread.Sleep (1000) between
Start and BeginOutputReadLine/BeginErrorReadLine.
This race exists because the WaitForExit in the background thread in the
Process, will first wait the process to finish, then try to wait for the
output to finish, but it will be null as BeginOutputReadLine has not been
called yet, then try to wait on error (same issue as output), and finally
call the Exited event, which will close the stdout and stderr TextWriter.
The call to BeginOutputReadLine and BeginErrorReadLine will finally happen
(which is still correct as the output and error of the Process has not
been closed yet), then calling the OutputDataReceived and ErrorDataReceived
callbacks which will try to write to the closed stdout and stderr
TextWriter.
Simply enqueuing a ThreadPool work item, which will wait for the process
to exit manually, simply resolve this issue, as we guarantee that the
call to WaitForExit happens after BeginOutputReadLine/BeginErrorReadLine,
and is not racing with it.