8

私の状況はこれです:

複数のスレッドが同じコレクション (add および addrange) に同時に書き込む必要があります。アイテムの順序は問題ではありません。すべてのスレッドが完了 (結合) し、メイン スレッドに戻ったら、収集したすべてのデータを foreach スタイルで高速に読み取る必要があります。すべてのスレッドが完了しているため、実際のロックは必要ありません。

「昔」では、おそらくリストでこれにリーダーライターロックを使用していましたが、新しい並行コレクションでは、より良い代替手段があるのではないかと思います。ほとんどの並行コレクションは、リーダーも並行スレッド上にあると想定しているように見えるため、どれを理解することはできません。

4

3 に答える 3

6

のコレクションを使用したくないと思いますSystem.Collections.Concurrent。これらは通常、同時読み取りを可能にするために余分なオーバーヘッドがあります。

あなたが多くの論争を持っていない限り、あなたはおそらく単純なものをロックしList<T>てそれに追加する方が良いでしょう。リストのサイズが変更されると、多少のオーバーヘッドが発生しますが、かなりまれになります。

ただし、この場合におそらく行うことは、共有スレッドではなくList<T> スレッドごとに追加し、処理の最後にそれらをマージするか、各コレクションのすべての要素を単純に反復することです。

読み取りの準備ができたら(読み取りごとのペナルティをバイパスして)、を使用してからまたはをConcurrentBag呼び出すこともできますが、挿入の速度は、単純なの手動書き込みロックよりも少し遅い場合があります。それは本当に競合の量に依存します。パーティション分割についてはかなり良いですが、ご存知のように、読み取りと書き込みの同時実行を対象としてます。.ToArray()GetEnumerator()ListConcurrentBag

いつものように、あなたの特定の状況をベンチマークしてください!マルチスレッドのパフォーマンスは、実際の使用法の多くに大きく依存します。データの種類や挿入の数などは、結果を劇的に変化させます。ほんの一握りの現実は、1ガロンの理論に値します。

于 2013-02-01T03:03:04.743 に答える
5

アイテムの順序は問題ではありません。すべてのスレッドが完了 (結合) し、メイン スレッドに戻ったら、収集したすべてのデータを読み取る必要があります。

スレッドセーフなコレクションの要件をまったく述べていません。書くと同時に読むことはないので、1 つのコレクションを共有しても意味がありません。また、順序は関係ないため、すべての書き込みが同じコレクションに対して行われることも問題ではありません。とにかく順序がランダムになるので、それは問題ではありません。

したがって、各スレッドに独自のコレクションを与えるだけで、ロックは必要ありません。その後、それらを 1 つずつ繰り返します。ロックは必要ありません。

于 2013-02-01T04:21:27.720 に答える
4

試してみてくださいSystem.Collections.Concurrent.ConcurrentBag

コレクションの説明から:

スレッドセーフな、順序付けられていないオブジェクトのコレクションを表します。

これは、複数のスレッドを処理し、アイテムの順序は重要ではないという基準を満たしていると思います。後でメインスレッドに戻ったら、コレクションをすばやく繰り返し処理して、各アイテムに対応できます。

于 2013-02-01T02:44:44.247 に答える