从子进程的stdout同步异步读取

时间:2012-10-29 11:09:16

标签: c# io synchronization multiple-processes

我有应用程序启动子process并异步处理其stdout。问题是异步操作需要一些时间,我希望负责流程执行的方法在所有异步IO操作完成后结束

我有这样的代码:

using System.Diagnostics;

Process process = new Process();
// ...
process.OutputDataReceived += new DataReceivedEventHandler(this.OnRecvStdOut);
process.ErrorDataReceived += new DataReceivedEventHandler(this.OnRecvStdErr);
// ...
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
// ...
process.WaitForExit();

现在我正在寻找一种方法告诉程序等待所有IO(OnRecvStdOut)操作完成。

我虽然使用了System.Threading个类之一,但我不确定哪个类最适合这个以及如何做到这一点,最好的方法可能是:

public void OnRecvStdOut(...)
{
    something.Increase();
    // the stuff that takes so long
    something.DecreaseAndSignal();
}

主要功能:

something.WaitUntilZero();

注意:我希望同时处理StdErrStdOut Something不能依赖Wait } Signal将被调用,因为Increase()DecreaseAndSignal()对将在Wait发生之前多次调用。

我想到的第二件事是能够多次发出信号(无需处理信号)并在主要功能中使用循环,如:

while( ioOperations > 0){
    something.WaitForSignal(500);
}

编辑:当前工作解决方案:

我想出了这个似乎有用的东西:

using System.Threading;

protected int IOCount = 0;
protected AutoResetEvent _IOSyncEvent = new AutoResetEvent(false);

public void OnRecvStdOut(...)
{
    Interlocked.Increase( ref IOCount);
    // the stuff that takes so long
    Interlocked.Decrease( ref IOCount);
    IOSyncEvent.Set();
}

// After process.WaitForExit()
while( IOCount > 0){
    // 250 for a case that signal occurs after condition and before wait
    IOSyncEvent.WaitOne(250); 
}

但是,我很感激任何注意事项如何做到这一点“良好实践方式”或者我可能面临的实施风险。

1 个答案:

答案 0 :(得分:1)

使用CountdownEvent设置为2.每个数据都收到回调,检查x.EndOfStream标志(其中x是进程对象上的standardoutput或standarderror)。如果是EOF,则表示倒计时。它将起作用,因为标准和错误输出流最终将发出事件的信号。一旦两者发出信号,等待就会返回。这也是一种非常有效的方式。