Yes, so to avoid sleep I always prefer to use WaitHandle.
This way you can signal from one thread to another when something changed and need to be done.
I can see you already created a wait variable but not using it. So just instead of Thread.Sleep just do wait.WaitOne().
And then some other place, where you read the results I assume, just signal this handler by wait.Set().
Now, another things is, since you using Shell, there suppose to be a way to send a kill signal, similar to Ctrl-C, which will tell terminal to kill this command, so I would look into that.
I have an example on how to do it in SshCommand file and should be used something like on of those choice:
I think I tried that but it didnt work well for me, but again, I dont think I tried it with Shell, so you might give it a shot and see if it works.
As far as reading more efficient. I have a class called PipeStream, you might want to use that.
Then you just need to create it once and not recreate it every time since once you read the information from it, it will be removed from the stream.
Hope it helps,