Hello,
I hope this is the correct place to post this question, please let me
know if I am wrong.
When performing an asynchronous read of the standard or error output
from a command line utility in .NET 2.0 with BeginOutputReadLine and
BeginErrorReadLine of the System.Diagnostics.Process class, I am
noticing that not all the output is being sent to my application before
the process terminates.
Example:
"test.exe" will print 10 lines of text, then terminate:
"Hello world!"
"Hello world!"
...
In my code, I do the following:
Process utility= new Process();
utility.StartInfo.FileName = "test.exe";
utility.StartInfo.UseShellExecute = false;
utility.StartInfo.RedirectStandardOutput = true;
utility.StartInfo.RedirectStandardError = true;
utility.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
utility.StartInfo.CreateNoWindow = true;
utility.OutputDataReceived += gatherUtilityOutput;
utility.ErrorDataReceived += gatherUtilityOutput;
utility.Start();
utility.BeginOutputReadLine();
utility.BeginErrorReadLine();
// Wait up to 30 seconds for the process to finish
if (!utility.WaitForExit(30000))
throw new Exception("Timed out reading from utility.");
utility.Close();
processUtilityOutput();
The gatherUtilityOutput callback just simply puts the output into a
string builder. After the utility finishes, when processUtilityOutput
is called, sometimes there is not 10 lines of "Hello world!", but
rather there is only one line. Not all of the output has been received
by my application. Is there any way to gather all the output besides
using my own thread to read the data synchronously? (which would not
take advantage of these new .NET features)
Eventually, all data IS collected in my callbacks, but this is sometime
AFTER the process is terminated, and therefore the data is not fully
collected when I intend to process it. Is there a way to know when all
data has been received?
dberlin@deadpirate.com - 23 Jun 2006 20:28 GMT
I may have answered my own question by looking at the .NET library
source with Reflector. It appears that when one uses the WaitForExit
function with a timeout, there is no guarantee that all the data has
been received asynchronously, but if one calls WaitForExit with no
timeout value, there is code in that method that will receive all the
output. My solution is to call WaitForExit() AFTER I know the process
has already exited by a successful return from WaitForExit(timeout).
This causes the code that reads all remaining pending async data to be
executed. So far, it looks as though this works.
> Hello,
>
[quoted text clipped - 50 lines]
> collected when I intend to process it. Is there a way to know when all
> data has been received?
AyAn4m1 - 22 Jul 2006 05:20 GMT
I'm having the same issues... Apparently it has something to do with the buffer of the underlying StandardOutput stream, but if you try and call StandardOutput.BaseStream.Flush() it gives an error saying that you can't mix sync and async methods. Anyone know anything more?