3

I'm redirecting standard output from a Process within a C# NET 4 application then using a BinaryReader on a separate thread to read it. (It's binary data; chunks of video that require parsing for delimiters)

All works fine until the process outputs the final byte, at which point the BinaryReader hangs, blocking on ReadBytes(int) This is no good for me; I need to know when the stream has reached an end, in order to write the final chunk of data to disk.

I would use the Process.Exited event and treat this as equivalent to EOS (then kill the thread). But Process.Exited is never raised: presumably the process is waiting for my app to close the stream before it dies.

Unfortunately, this question seems to indicate that any call to the higher-level properties of StandardOutput, such as StandardOutput.EndOfStream will cause the default StreamReader of the StandardOutput to be accessed, so I assume this approach is out.

Is there an easy way that I can either detect the end of the stream, or make the BinaryReader time out?

{
  runningProcess.Start();

 // Read standard output on a new thread
 thrdReadStandardOut = new Thread(new ThreadStart(ReadStandardOutput));
 thrdReadStandardOut.Start(); 

}

...

void ReadStandardOutput()
        {
            Monitor.Enter(runningProcess);  // keep this section thread safe

            var br = new BinaryReader(runningProcess.StandardOutput.BaseStream);
            bool abort = false;

            while (!abort)
            {
                try
                {
                    byte[] bytes = br.ReadBytes(256);

                    if (StandardOutputReceived != null)
                        StandardOutputReceived(this, new GenericEventArgs<byte[]>(bytes));
                }
                catch (EndOfStreamException)
                {
                    abort = true;
                }
            }

            Monitor.Exit(runningProcess);
        }
Community
  • 1
  • 1
Carlos P
  • 3,928
  • 2
  • 34
  • 50

1 Answers1

1

The Process.Exited event will only be raised if you've set Process.EnableRaisingEvents to true. If you do that, you should be getting process exit notifications via Process.Exited or via the synchronous Process.WaitForExit method.

If you're still not getting this event, see if your child process is terminating gracefully (though even then I would still expect Exited to fire).

Chris Schmich
  • 29,128
  • 5
  • 77
  • 94
  • Thanks Chris, I didn't know that. Your answer doesn't allow me to detect the end of the stream, or time out the BinaryReader, but it does allow me to implement the workaround I alluded to in my question, so I'm marking this as the accepted answer. – Carlos P Apr 25 '11 at 18:03