22

以前に同時キューを使用したことがありません。

while ループで、以下のように TryDequeue を使用しても問題ありませんか? これは永遠に行き詰まることはありませんか?

var cq = new ConcurrentQueue<string>();
cq.Enqueue("test");

string retValue;

while(!cq.TryDequeue(out retValue))
{
    // Maybe sleep?
}

//Do rest of code
4

2 に答える 2

18

取り出された項目が存在するまでループは実際には終了せず、キューに取り出される項目がある場合は最終的に終了するという意味で安全です。キューが別のスレッドによって空にされ、それ以上アイテムが追加されない場合、もちろんループは終了しません。

そのすべてを超えて、あなたが持っているのは忙しいループです。これは事実上、常に回避する必要があります。より多くのアイテムを要求するキューを絶えずポーリングしてプロセスの CPU 時間と労力を浪費するか、またはスリープしてしまい、キュー内のアイテムが追加されるとすぐに実際には使用しない (そしてそれでも無駄になる) かのいずれかです。キューをポーリングするためだけにコンテキスト スイッチに時間と労力を費やす必要があります)

代わりに、「私が取るアイテムがあるまで待ちたい」という立場にいることに気付いた場合、あなたがすべきことはBlockingCollection. これは、さまざまなタイプの並行コレクションをラップし、取得できるアイテムができるまでブロックするように特別に設計されています。コードを に変更して、コードをqueue.Take()より簡単に記述できるようにし、何を行っているかを意味論的に記述し、明確に正しく、著しく効果的で、完全に安全にすることができます。

于 2014-05-23T14:50:57.713 に答える