7

コンシューマーがツリーの各レベルでいくつかの作業を行ってから、ツリーを再帰的に下って次のレベルで同じ作業を実行する必要があるという再帰的な問題があります。

ConcurrentBag/BlockingCollectionなどを使用してこれを並行して実行したいと思います。このシナリオでは、キューのコンシューマーはキューのプロデューサーでもあります。

私の問題はこれです:BlockingCollectionを使用すると、アイテムをデキューし、新しいアイテムをキューに入れるための非常に単純なforeachロジックを記述できます-キューが空の場合、ブロッキングコレクションは正しくブロックされ、他のいずれかによって新しい作業が生成されるのを待ちます消費者。

しかし、すべての消費者がブロックしているかどうかをどうやって知ることができますか?!

CompleteAdding()については知っていますが、実際に完了するのは、すべてのプロデューサーがプロデュースを完了し、キューが空になったときだけであるため、それは役に立たないようです。 「無料」でCompleteAdding()を設定します。これを検出する方法はありますか?(おそらく、ブロックすると発火し、ブロックを解除すると再び発火する可能性のあるイベントですか?)

foreachを使用せずに、手動でwhile(!complete)ループを作成し、TryTakeを使用することで、これを手動で処理できますが、手動でスリープする必要があります。これは非効率的です(ブロッキングコレクションを使用する理由とそもそも同時収集!)ループを通過するたびに、TryTakeがfalseの場合、アイドルフラグを設定し、キューが空で、すべてのスレッドがアイドル状態であるかどうかをマスターにチェックさせ、完全フラグを設定します。しかし、繰り返しになりますが、これは厄介なようです。

直感的に、ブロッキングコレクションを使用してこれを行う方法があると言われていますが、私はそこにたどり着くことができません。

とにかく、誰もが消費者がプロデューサーであるときの良いパターンを持っており、すべてのブロックをいつリリースするかを検出できるのは素晴らしいことです

4

0 に答える 0