How to Asynchronously Read the Standard Output Stream and Standard Error Stream at Once

How to asynchronously read the standard output stream and standard error stream at once

I found the answer:

The output streams are buffered. There is no way to get the true
sequential order of the items inserted into the streams. In fact it
makes little sense as both streams can be written too at the same
time. They are independent of each other. Therefore the best you can
do is get the sequential output from each one as they arrive.

Generally this is not an issue though as almost all console apps use
standard output for both output and error messages. The error stream
is used by some apps but the messages are generally duplicates of the
errors generated in the output stream.

Source: http://social.msdn.microsoft.com/Forums/uk/csharpgeneral/thread/192b6df7-9437-42cf-81c1-c125021735ba

Asynchronous redirect StandardOutput and StandardError

The reason behind different orders is that when in console, a single output stream is indeed assigned to both "standard output" and "error output", and when called by your application, there are two streams that are not synchronized, thus your SortOutputHandler events are called in any order (if there were extremely long pauses between writes to the outputs or flushes it could get ordered correctly by chance).

The only solution you have to get this well sorted is to ensure that there is a single stream. The problem is that I am not aware of a solution allowing this using the ProcessStartInfo class.
One possibility would be to start the process in "pause" mode, then redirect forcefully its standard error handle to the output handle, then let it run (as cmd.exe does)

In C#, how can I get the output of a process as string while also terminating process if taking too long?

You can use OutputDataReceived event

StringBuilder sb = new StringBuilder();
proc.OutputDataReceived += (x,s) => sb.AppendLine(s.Data);

proc.Start();
proc.BeginOutputReadLine();

proc.WaitForExit(0 * 60 * 1000);
var output = sb.ToString();

Reading console stream continually in c#

You're calling ReadToEnd which will obviously block until the process terminates. You can repeatedly call Read or ReadLine instead. However, you should consider either doing this in a different thread or using events such as OutputDataReceived to do this. (If you're using events, you need to call BeginOutputReadLine to enable the events - see the MSDN examples for details.)

The reason for potentially reading on a different thread is that if you need to read from both standard error and standard output, you need to make sure the process doesn't fill up its buffer - otherwise it could block when writing, effectively leading to deadlock. Using the asynchronous approach makes it simpler to handle this.



Related Topics



Leave a reply



Submit