PortSet<ActualResult, Exception>
複雑な一連のタスクがあるため、エラー処理を実装すると、try/catch ブロックや、小さなタスクごとにChoice レシーバーなどを使用するときに、コードがすぐに肥大化する可能性があります。
ありがたいことに、CCR は、タスクのグラフのより一般的な方法である因果関係で例外を処理するメカニズムを提供しているようです。典型的な例は次のようになります。
Port<Exception> exceptionPort = new Port<Exception>();
Dispatcher.AddCausality(new Causality("some job", exceptionPort));
Arbiter.Activate(
dispatcherQueue,
Arbiter.Receive(false, exceptionPort, ex => Console.WriteLine(ex)));
// now schedule the real tasks
私の場合、CCR を使用してスキャッター/ギャザー シナリオを実装し、「ジョブ」を並列化されたタスクの束に分割する、コンピューティング集約型のアプリケーションがあります。(さらに、これらのジョブを複数同時に実行できます。) 1 つのタスクが失敗した場合、ジョブの残りのタスクをすべて停止したいが、他のジョブは停止したくない。(パズルのピースが欠けている場合、結果は役に立たないので、これに取り組み続けることは単に CPU 時間の無駄になります。)
問題は、停止を実装するための最良の方法は何かということです。
1つのアイデアは次のとおりです。
- 単一の
Dispatcher
インスタンスを作成し、アプリケーションの有効期間にわたって保持します。 DispatcherQueue
「ジョブ」(タスクのグループ)ごとに新しいものを作成します。Causality
を作成した直後に を追加しDispatcherQueue
ます。- 例外キューのハンドラで、 を呼び出し
Suspend()
ますDispatcherQueue
。 - ディスパッチャ キューを破棄する前に、因果関係を取り除いてください。
この提案がベスト プラクティスとみなされるのか、それとも、そのような (おそらくかなり一般的な) シナリオに対処するためのより良いアプローチがあるのだろうかと思います。