Consider the following program. Here I start a simple process and want to deal with it's output. I assumed that would be the case after WaitForExit
has returned, but it turns out, that I have to wait upto a full second until that output actually arrives in my program.
static void Main(string[] args)
{
using var p = new Process();
p.StartInfo.FileName = "echo";
p.StartInfo.Arguments = "I apologize for being late";
p.StartInfo.CreateNoWindow = false;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
var stdError = new StringBuilder();
var stdOutput = new StringBuilder();
p.ErrorDataReceived += (sender, args) => stdError.AppendLine(args.Data);
p.OutputDataReceived += (sender, args) => stdOutput.AppendLine(args.Data);
p.Start();
p.BeginErrorReadLine();
p.BeginOutputReadLine();
// without the int-parameter here, it works
while (!p.WaitForExit(10000))
Console.WriteLine("still waiting...");
string a = stdOutput.ToString();
string b = stdError.ToString();
Thread.Sleep(1000);
string c = stdOutput.ToString();
string d = stdError.ToString();
Console.WriteLine("output before sleep: " + a);
Console.WriteLine("error before sleep: " + b);
Console.WriteLine("output after sleep: " + c);
Console.WriteLine("error after sleep: " + d);
}
output
output before sleep:
error before sleep:
output after sleep: I apologize for being late
error after sleep:
Here I would expect, that a
and c
have the exact same value. But that is not the case. How would I modify this example such that I reliable receive the full output of the process, but without calling Thread.Sleep(1000)
?
Notes:
- I want the reliable complete output of both stdOut and stdErr
- when I use
p.WaitForExit()
insteadp.WaitForExit(10000)
everything seems to work - When using
p.StandardOutput.ReadToEnd()
for both streams it seems to work. But I am told by the official documentation, that this would lead to deadlocks - when using
p.StandardError.ReadToEnd()
while using the async solution for the output, than the output still arrives late. - this is not a duplicate of Process WaitForExit not waiting because for them
p.WaitForExit()
without any parameter already doesn't work. Also they are not interested in the output at all.