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.
[quoted text, click to view] dberlin@deadpirate.com wrote:
> 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?