サブプロセス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();
OnRecvStdOut
現在、すべての IO( ) 操作が完了するまでプログラムに待機させる方法を探しています。
私はSystem.Threadingクラスのいずれかを使用することについて考えましたが、どのクラスがこれに最適で、結局これを行う方法がわかりません。おそらく最良の方法は次のとおりです。
public void OnRecvStdOut(...)
{
something.Increase();
// the stuff that takes so long
something.DecreaseAndSignal();
}
そしてメイン関数では:
something.WaitUntilZero();
StdErr
注: と の両方をStdOut
並行して処理できるようにしたいと思います。 とのペアが発生する前に何度も呼び出されるため、が と同じくらい呼び出されるとは限りSomething
ません。Wait
Signal
Increase()
DecreaseAndSignal()
Wait
2番目に頭に浮かんだのは、(シグナルを処理する必要なしに)何度もシグナルを送信し、次のようなメイン関数でループを使用できるものでした。
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);
}
しかし、この「優れた方法」を実行する方法、または私が考えた実装の潜在的なリスクについてのメモをいただければ幸いです。