tags:

views:

117

answers:

2

I'm starting a process within my C# application which runs a console application. I've redirected standard input and output, and am able to read a few lines via StandardOutput.ReadLine(). I'm convinced I have the ProcessStartInfo configured correctly.

The console application, when started, outputs a few lines (ending with a "marker" line) and then waits for input. After receiving the input, it again outputs a few lines (ending again with a "marker" line), and so on. My intention is to read lines from it until I receive the "marker" line, at which point I know to send the appropriate input string.

My problem is that, after several iterations, the program hangs. Pausing the debugger tends to place the hang within a call to StandardOutput.EndOfStream. This is the case in the following test code:

while (!mProcess.StandardOutput.EndOfStream) // Program hangs here.
{
    Console.WriteLine(mProcess.StandardOutput.ReadLine());
}

When I'm testing for the "marker" line, I get the same kind of hang if I attempt to access StandardOutput.EndOfStream after reading the line:

string line = "";
while (!isMarker(line))
{
    line = mProcess.StandardOutput.ReadLine();
}
bool eos = mProcess.StandardOutput.EndOfStream; // Program hangs here.

What might I be doing that causes this property to perform so horribly?

+1  A: 

Did you wait for the process to finish before reading from it's standard output:

mProcess.WaitForExit();
Darin Dimitrov
No; the intention is to interact with the console application.
TreDubZedd
+1  A: 

You cannot use EndOfStream reliably here. The StreamReader.EndOfStream property will call StandardOutput.Read() if it doesn't have any characters buffered. That Read() call will block if the process isn't sending anything to its output pipe and doesn't close it. Which is pretty much guaranteed to happen since it will be waiting for input. EndOfStream won't return true until the process has closed its end of the output pipe and the StreamReader has consumed all its buffered characters. At program termination.

Using BeginOutputReadLine() might be a better way to detect the "marker" line. Beware that the callback happens on another thread. Also note that it shouldn't be necessary to wait for the process to send the marker, anything you write will be buffered until the process is ready to read it. Beware that the buffers are smallish, deadlock is possible.

Hans Passant