C# 使用二进制读取器重定向.NET中的标准输出-检测EOS/强制超时

C# 使用二进制读取器重定向.NET中的标准输出-检测EOS/强制超时,c#,.net,process,io,C#,.net,Process,Io,我正在重定向C#NET 4应用程序中进程的标准输出,然后使用单独线程上的二进制读取器读取它。(这是二进制数据;需要解析分隔符的视频块) 在进程输出最后一个字节之前,一切都正常工作,此时BinaryReader挂起,阻塞ReadBytes(int)这对我没有好处;我需要知道流何时结束,以便将最后一块数据写入磁盘 我将使用Process.Exited事件并将其视为等效于EOS(然后终止线程)。但是Process.Exited从未被引发:大概进程正在等待我的应用程序在流死之前关闭它 不幸的是,这似乎表

我正在重定向C#NET 4应用程序中进程的标准输出,然后使用单独线程上的二进制读取器读取它。(这是二进制数据;需要解析分隔符的视频块)

在进程输出最后一个字节之前,一切都正常工作,此时BinaryReader挂起,阻塞ReadBytes(int)这对我没有好处;我需要知道流何时结束,以便将最后一块数据写入磁盘

我将使用Process.Exited事件并将其视为等效于EOS(然后终止线程)。但是Process.Exited从未被引发:大概进程正在等待我的应用程序在流死之前关闭它

不幸的是,这似乎表明对StandardOutput的更高级别属性(如StandardOutput.EndOfStream)的任何调用都会导致访问StandardOutput的默认StreamReader,因此我假设这种方法已过时

有没有一种简单的方法可以检测流的结尾,或者让BinaryReader超时

{
  runningProcess.Start();

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

}

void ReadStandardOutput()
{
Monitor.Enter(runningProcess);//保持此部分线程安全
var br=新的二进制读取器(runningProcess.StandardOutput.BaseStream);
bool abort=false;
而(!中止)
{
尝试
{
byte[]bytes=br.ReadBytes(256);
如果(StandardOutputReceived!=null)
标准输出接收(这是新的GenericEventArgs(字节));
}
捕获(EndOfStreamException)
{
中止=真;
}
}
监视。退出(运行进程);
}
只有在设置为
true
时才会引发事件。如果您这样做,您应该通过
process.Exited
或同步方法获得进程退出通知


如果您仍然没有收到此事件,请查看您的子进程是否正常终止(即使如此,我仍然希望
退出
触发)。

谢谢Chris,我不知道这一点。您的回答不允许我检测流的结尾,也不允许超时BinaryReader,但它确实允许我实现我在问题中提到的解决方法,因此我将此标记为可接受的答案。
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);
        }