2

たとえば、私は行くことができます:

string[] keys = new string[items.Count];
items.Keys.CopyTo(keys);

アイテムは次のとおりです。

Dictionary<string, MyObject>

別のスレッドによって変更されている可能性のあるインスタンス? ( Keys プロパティにアクセスするときに Dictionary の内部動作がコレクションを反復するかどうかはわかりません。その場合、スレッドセーフではないことがわかっています)。

更新: Dictonary のサイズが行間で変化する可能性があるため、上記の例はスレッドセーフではないことに気付きました。しかし、どうですか:

Dictionary<string, MyObject> keys = items.Keys;
string[] copyOfKeys = new string[keys.Count];
keys.Keys.CopyTo(copyOfKeys );
4

2 に答える 2

3

いいえ、Dictionaryスレッドセーフではありません。スレッド セーフが必要で、.NET 4 以降を使用している場合は、ConcurrentDictionary.

MSDN から:

コレクションが変更されない限り、ディクショナリは複数のリーダーを同時にサポートできます。それでも、コレクションの列挙は本質的にスレッドセーフな手順ではありません。列挙が書き込みアクセスと競合するまれなケースでは、列挙全体の間、コレクションをロックする必要があります。読み取りおよび書き込みのために複数のスレッドがコレクションにアクセスできるようにするには、独自の同期を実装する必要があります。

于 2012-06-16T10:59:03.380 に答える
1

辞書が別のスレッドで変更されている場合、これを行うのは安全ではありません。最初に頭に浮かぶのは、辞書が内部バッファーのサイズを変更する可能性があることです。これは、同時反復ではうまく機能しません。

キーを変更せず、値のみを書き込んでいる場合、これは実際には安全なはずです。

とにかく、リスクが高すぎるので、そのようなコードを本番環境に入れません。.NET パッチによって の内部が変更され、Dictionary突然バグが発生した場合はどうなるでしょうか。他にも懸念事項があります。

ConcurrentDictionaryまたは他の安全な戦略を使用することをお勧めします。コードの正確さに賭ける必要はありません。

于 2012-06-16T10:59:07.123 に答える