12

外部 ConcurrentBag を設定するために Parallel.Foreach を使用しています。共通のリストも使用しようとしましたが、すべて正常に動作します。

私は運が良かったのですか、それとも ConcurrentBag の特別な範囲を逃したのですか?

4

3 に答える 3

18

あなたは幸運でした。Parallel.ForEachリストにデータを入力することはスレッドセーフではないため、最終的に問題が発生します。

MSDN によると、List<T>スレッド セーフではありません。

インスタンス メンバーは、スレッド セーフであるとは限りません。

List<T> は、コレクションが変更されない限り、複数のリーダーを同時にサポートできます。コレクションの列挙は、本質的にスレッドセーフな手順ではありません。列挙が 1 つ以上の書き込みアクセスと競合するまれなケースでは、スレッドの安全性を確保する唯一の方法は、列挙全体でコレクションをロックすることです。読み取りおよび書き込みのために複数のスレッドがコレクションにアクセスできるようにするには、独自の同期を実装する必要があります。

これには ConcurrentBag を使用する必要があります。これは、複数のリーダーとライターに対してスレッドセーフです。

于 2011-08-25T16:13:36.583 に答える
5

を使用Parallel.ForEachして a を入力していてList<T>、すべてが正常に機能している場合は、単に幸運です。メソッドはForEach複数のスレッドでコードを実行できるため、外部の通信はForEach同時更新を処理できるオブジェクトを使用する必要があります。 List<T>できませんがConcurrentBag<T>できます。

于 2011-08-25T16:13:17.730 に答える
2

ConcurrentBag が正解です。.NET 4.0 でのみ非常に低速です。これは .NET 4.5 で修正されました。http://ayende.com/blog/156097/the-high-cost-of-concurrentbag-in-net-4-0を参照してください。

ConcurrentStack と ConcurrentQueue の両方があなたの状況でも機能します...

于 2012-07-20T11:52:04.220 に答える