3

私はConcurrentStackを持っており、その各アイテムはいくつかのWebリソースへのURLです。また、N個のスレッド(実際にはTasks)があり、それぞれがスタックプロセスから1つのアイテムをポップし、いくつかの基準に応じて、このスタックまたは他の出力キューに結果(結果はコレクション)を追加します。これは、スタックが空になるまで実行する必要があります。

このプロセスの終了を認識し、このタスクを停止するためのよりエレガントな方法は何ですか?つまり、スタックが空であり、スタックにアイテムを追加する実行中のタスクがないことを認識する方法

4

2 に答える 2

2

終了条件は、スタックから読み取っているすべてのタスクがすべてアイテムがスタックに積み上げられるのを待っているときのようです。もちろん、これは、タスクがそのイベントを受動的に待機する方法を提供する場合にのみ発生します。他の回答で示唆されているようBlockingCollectionに、クラスの上で使用してConcurrentStack同期を実装できます。

終了に関して、最も簡単な方法は、タスク (終了タスク) がその条件を待機するようにすることです。他のすべてのタスクは、待機中のタスクの数を表す整数を操作し、コレクションでブロックする前にそれをインクリメントし、アイテムを取得するときにそれをデクリメントします。 . その数がスタックの可能なリーダーの総数に達すると、現在アイテムを取得しようとしているタスクは、コレクションでブロックする前に条件変数をトリガーし、終了スレッドをウェイクアップします。

于 2013-03-21T09:37:56.443 に答える
1

IProducerConsumerCollectionを実装する ConcurrentStack を使用しているため、 (このコンストラクターを使用して作成することにより) BlockingCollectionでラップできます。これにより、データの終わりを示すことができるCompleteAdding()メソッドが提供されます。

基礎となる IProducerConsumerCollection はアイテムを格納するために使用されるため、LIFO であるという点ではスタックのように動作します。

データを消費するには、 GetConsumingEnumerable()オーバーロードのいずれかを使用するように切り替える必要があります。これは、正常なタスクの終了を処理するための最もエレガントで強力な方法であることがわかりました。

おそらくこれはあなたのために働くかもしれませんか?

于 2013-03-21T08:52:36.953 に答える