Non-blocking Stream read for Std.Out wanted!

  • Thread starter Thread starter Dmitry Bond.
  • Start date Start date
D

Dmitry Bond.

Hi All.

I need non-blocking stream read to read std.out of running program.
The scenario I wish to implement is the following:
1) run program, redirect std.in and std.out.
2) write to std.in, read answers from std.out, analyse answers and write to
std.in again...

With the step 1 all is ok - I know how to do it - there are samples in MSDN.
But with step 2 I have problems...
Below you could see the code I tried to use for non-blocking read:

private string NonBlockingRead(StreamReader sr)
{
sr.DiscardBufferedData();
StringBuilder sb = new StringBuilder(0x200);
while (sr.Peek() >= 0)
{
sb.Append((char)sr.Read());
}
return sb.ToString();
}

Unfortunately it does not work properly.
The problem appears when when StreamReader try to read next portion of data
into internal buffer - it just hungs and I can not do anything with it.

Please help me with this stuff.

I inspected StreamReader internals with .NET Reflector and I'm start to
affraid that it is impossible at all in .NET. :-(((
I hope I mistaken and there is a solution because otherwise I have to
rollback to using unmanaged C++ or Delphi code that is undesirable in my
case...


WBR,
Dmitry.

ps. .NET framework is 1.1. But if it is possible in 2.0 please let me know
too.
 
Finally I almost solved this problem by creating one more thread that read
std.out, see code below.
I said "almost" because output sometimes hungs on half (looks like it wait
in StreamReader.ReadBuffer()) to see continue of std.out content I have to
issue one more command to std.in.
But the user interface now working fine (not hungs like it was before).

internal class MyProcess {
private Thread thrd = null;
private Thread thrd_stdout = null;
private Process proc = null;
private string outputText = "";
private StringBuilder outputTextSB = new StringBuilder(0x8000);

public MyProcess() {
// [...]
this.thrd_stdout = new Thread(new ThreadStart(this.DoReadStdOut));
}

// [...]

// reading std.out and collect in outputTextSB
protected void DoReadStdOut() {
while (this.thrd_stdout.IsAlive) {
this.proc.StandardOutput.DiscardBufferedData();
while (this.proc.StandardOutput.Peek() >= 0) {
lock (this.outputTextSB) {
this.outputTextSB.Append((char)this.proc.StandardOutput.Read());
}
}
Thread.Sleep(50);
}
}

// [...]
// to access read std.out content
public string OutputText {
get {
lock (this.outputTextSB) {
this.outputText = this.outputTextSB.ToString() + "\r\n";
return this.outputText;
}
}
}
// [...]
}
 
Back
Top