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
How to Add the Same Column to All Entities in Ef Core
How to Implement "Access-Control-Allow-Origin" Header in ASP.NET
Lambda Expressions in Immediate Window for VS2015
Alternative to Multiple String.Replaces
Troubleshooting "Program Does Not Contain a Static 'Main' Method" When It Clearly Does...
Datagridview with Button Control - Delete Row
Changing the View for a Viewmodel
Extract All Strings Between Two Strings
How to Run External Program via a C# Program
C# Waiting for Multiple Threads to Finish
Dtd Prohibited in Xml Document Exception
How to Create an Instance from a String in C#
Making a Web Request to a Web Page Which Requires Windows Authentication
Get Window State of Another Process
Formatting Datetime in ASP.NET Core 3.0 Using System.Text.JSON