3

IsEmpty を調べると、MSDN で次のことに気付きました。

ただし、このコレクションは同時にアクセスされることを意図しているため、IsEmpty が返された後に別のスレッドがコレクションを変更し、結果が無効になる場合があります。

確かにこれは本当ですが、キューが空かどうかを確認するときに ConcurrentQueue が読み取りバリアを使用しないことも意味しますか?

同時キューが空であるかどうかを別のスレッドでチェックするコードが必要です。このようなもの:

while (!queue.IsEmpty)
{
}

ただし、ConcurrentQueue が読み取りバリアを使用しない場合は、次のように、適切なデータを確実に読み取るために独自のメモリ バリアを追加する必要があると思います。

Thread.MemoryBarrier();
while (!queue.IsEmpty)
{
    Thread.MemoryBarrier();
}

(ところで: これらはケースを説明するための最小限の例にすぎません。実際にはもっと多くのコードがあります)。

私の観察は正しいですか?または、ConcurrentQueue はこれを処理し、最初の実装は機能しますか? (たとえば、「同時実行」に期待すること)?

そして、「カウント」はどうですか?MSDN で答えが見つかりません... 同じ話ですか?

4

1 に答える 1

6

いいえ、メモリバリアとは関係ありません。テストの直後に、他の何かが入り込んで、キューに何かを追加したり、キューから何かを削除したりする可能性があります。

を実際に使用するべきではありませんIsEmptyTryDequeue代わりに使用してください。またはを使用しBlockingCollectionます。

IsEmptyまたはをいじっている間にキューを「ロック」するコードを書き始めたくありませんCount

(もちろん、何をしようとしているかにもよりますが、はるかに優れているためConcurrentQueue、最近はほとんど使用しません。)BlockingCollection

于 2013-03-22T10:15:57.147 に答える