外部 ConcurrentBag を設定するために Parallel.Foreach を使用しています。共通のリストも使用しようとしましたが、すべて正常に動作します。
私は運が良かったのですか、それとも ConcurrentBag の特別な範囲を逃したのですか?
外部 ConcurrentBag を設定するために Parallel.Foreach を使用しています。共通のリストも使用しようとしましたが、すべて正常に動作します。
私は運が良かったのですか、それとも ConcurrentBag の特別な範囲を逃したのですか?
あなたは幸運でした。Parallel.ForEach
リストにデータを入力することはスレッドセーフではないため、最終的に問題が発生します。
MSDN によると、List<T>
スレッド セーフではありません。
インスタンス メンバーは、スレッド セーフであるとは限りません。
List<T> は、コレクションが変更されない限り、複数のリーダーを同時にサポートできます。コレクションの列挙は、本質的にスレッドセーフな手順ではありません。列挙が 1 つ以上の書き込みアクセスと競合するまれなケースでは、スレッドの安全性を確保する唯一の方法は、列挙全体でコレクションをロックすることです。読み取りおよび書き込みのために複数のスレッドがコレクションにアクセスできるようにするには、独自の同期を実装する必要があります。
これには ConcurrentBag を使用する必要があります。これは、複数のリーダーとライターに対してスレッドセーフです。
を使用Parallel.ForEach
して a を入力していてList<T>
、すべてが正常に機能している場合は、単に幸運です。メソッドはForEach
複数のスレッドでコードを実行できるため、外部の通信はForEach
同時更新を処理できるオブジェクトを使用する必要があります。 List<T>
できませんがConcurrentBag<T>
できます。
ConcurrentBag が正解です。.NET 4.0 でのみ非常に低速です。これは .NET 4.5 で修正されました。http://ayende.com/blog/156097/the-high-cost-of-concurrentbag-in-net-4-0を参照してください。
ConcurrentStack と ConcurrentQueue の両方があなたの状況でも機能します...