2

From the MSDN example of using stdoutput of newly created process:

    // This is the code for the base process
    Process myProcess = new Process();
    // Start a new instance of this program but specify the 'spawned' version.
    ProcessStartInfo myProcessStartInfo = new ProcessStartInfo(args[0], "spawn");
    myProcessStartInfo.UseShellExecute = false;
    myProcessStartInfo.RedirectStandardOutput = true;
    myProcess.StartInfo = myProcessStartInfo;
    myProcess.Start();
    StreamReader myStreamReader = myProcess.StandardOutput;
    // Read the standard output of the spawned process. 
    string myString = myStreamReader.ReadLine();
    Console.WriteLine(myString);
    myProcess.WaitForExit();
    myProcess.Close();

If instead of myStreamReader.ReadLine() I'm using myStreamReader.ReadToEnd() shall I still use myProcess.WaitForExit()? Or ReadToEnd() will wait until the process is finished?

Roman Dzhabarov
  • 521
  • 4
  • 10
  • 1
    Why not ask the real question behind the question, what do you want to achieve? `ReadToEnd()` will simply read everything in the stream and does not *necessarily* affect `WaitForExit()`, – Chibueze Opata Sep 10 '12 at 19:34
  • The scenario is, I'm running another process and want to read all from its output and make sure I read all the info child process generated. – Roman Dzhabarov Sep 10 '12 at 19:45
  • Either one you use, you'll still be able to achieve the same output. The major issue is how you implement your reading of the process output. I'll post an answer shortly. – Chibueze Opata Sep 10 '12 at 20:12

2 Answers2

2

EDIT: Sorry for the diversion, to directly answer your question. Yes, you need to call Process.WaitForExit();. This will ensure that the process has yielded all its output before you call ReadToEnd()

ReadToEnd is synchronous function. Hence if you don't call it in your code, it will block your main thread until it captures only the first output from the StandardOutput, then that's it. But using WaitForExit will ensure that you have everything.

Also you might consider doing an asynchronous read of the process's output, see this MSDN Example that implements OutputDataRecieved

Chibueze Opata
  • 9,856
  • 7
  • 42
  • 65
  • My original question is if I use string myoutput = myStreamReader.ReadToEnd(); Shall I call myProcess.WaitForExit(); or not. – Roman Dzhabarov Sep 10 '12 at 20:42
  • Based on what you said. What will happen if I do not call WaitForExit(), will I be able to read begining of output? no output? – Roman Dzhabarov Sep 10 '12 at 21:02
  • 1
    Why do you think it's required to call WaitForExit()? in my sample application the execution of main thread is blocked when ReadToEnd() gets executed and once child process exited ReadToEnd() finishes as well. – Roman Dzhabarov Sep 10 '12 at 21:29
  • ReadToEnd() does not wait until the process gets finished. It's synchronous. In other words, if you don't use Process.WaitForExit(), you'll only receive the first output the process writes to the standard output. – Chibueze Opata Sep 10 '12 at 23:17
  • That's not true: you'll only receive the first output the process writes to the standard output. If you write simple application when you create process which does console.writeline("blah") several times, you'll get it. – Roman Dzhabarov Sep 10 '12 at 23:23
  • @RomanDzhabarov: Sorry to say this, but you have a bad understanding of how this works. An application that writes to the output via Console.WriteLine several times all end up producing one Standard Output. If for instance your spawned Console Application requests an input from the user before it writes further to the output, you'll not get it. Read the [MSDN documentation on Process.StandardOutput](http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput.aspx). – Chibueze Opata Sep 11 '12 at 09:19
  • You said: you'll only receive the first output the process writes to the standard output. What is first output? you are saying all end up producing on std output then. – Roman Dzhabarov Sep 12 '12 at 02:30
  • as per input you'll wait forever unless you redirectedstdinput also and write to input stream by parent process. – Roman Dzhabarov Sep 12 '12 at 02:32
  • This answer is just plain wrong, AFAICT: https://stackoverflow.com/questions/139593/processstartinfo-hanging-on-waitforexit-why – Clément Mar 19 '22 at 08:58
  • @Clément I was quite young when I answered this and while the communication is not very clear, it's well in line with the link you posted. The standard output is just a stream that can be read from or written to, the OP just wanted to know if `ReadToEnd` automatically calls `WaitForExit` and it certainly does not. Read their question and my answer to understand the context. I additionally offered the solution of using `OutputDataReceived` which is also the recommended answer in the link you shared. – Chibueze Opata Mar 22 '22 at 02:30
  • You write: *Yes, you need to call Process.WaitForExit(); … before you call ReadToEnd()*, but it's *never* right to call `WaitForExit` first. [MSDN](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.standardoutput?view=net-6.0): "A deadlock condition can result if the parent process calls p.WaitForExit before p.StandardOutput.ReadToEnd". – Clément Mar 22 '22 at 04:13
  • @Clément I kinda disagree. You can actually call `WaitForExit` with a timeout. Can result in deadlock is not same as will result in a deadlock. The issue is usually people not having enough information about the processes they're spawning. Even as of then, I had practical experience spawning lots of processes from c#. And I referred to the same document you shared in my comments. There can be a deadlock yes, but you also won't capture everything if you don't wait which is why an asynchronous operation will trump any other alternative when possible. – Chibueze Opata Mar 22 '22 at 09:24
  • [This question/thread](https://stackoverflow.com/a/26722542/612717) highlights the counter-intuitive problem with WaitForExit in C#. – Chibueze Opata Mar 22 '22 at 09:30
1

"ReadToEnd" is a function stored in "StreamReader" object and I don't think it has something to do with waiting for a process to exit, however the "Process" class might handle that itself. By the way, all the abilities "StreamReader" has are not useful in the situation you mentioned.

In my point of view, "WaitForExit" should be called and as you did "Close" too. Because they will release some system resources that no method else can. As far as I know, "ReadToEnd" method has nothing to do with calling those two.

Cheers

Rikki
  • 3,338
  • 1
  • 22
  • 34
  • I want to make sure I read all what child process generated. So, in other words ReadToEnd() shall wait until the child exits otherwise this will not read all output data. That what I'm asking. Close - definetaly release resources, i do not think wait clean anythign though. – Roman Dzhabarov Sep 10 '12 at 19:50
  • As you said "ReadToEnd" will return every thing that the process wrote in the output stream, but the time you're calling it is important. You should wait for the operations inside the process to be completed then call the "ReadToEnd" method before closing the process and disposing resources. And of cource the method itself does not wait for anything. Cheers – Rikki Sep 10 '12 at 19:57
  • This is not true, that ReadToEnd() doesn't wait for anything.. It waits but I need to make sure that it waits until child process exits. – Roman Dzhabarov Sep 10 '12 at 20:04
  • I'm sure that even if it waits, Process class will close the output stream after the process exited. And ReadToEnd will wait until the stream closes by someone. Cheers – Rikki Sep 10 '12 at 20:08