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.
Dmitry Bond. - 15 Dec 2005 08:13 GMT
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;
}
}
}
// [...]
}
> Hi All.
>
[quoted text clipped - 3 lines]
> 2) write to std.in, read answers from std.out, analyse answers and write to
> std.in again...