2017-09-05 15 views
-2

私は方法があります。IDictionaryをとる関数にConcurrentDictionary型を渡すことは安全ですか?

void foo(IDictionary<string, object> data) { 
    data["key1"] = getValue1(); 
    data["key2"] = getValue2(); 
} 

を次のように私は現在、それを呼び出す:辞書が複数のスレッドに移入されているので

var serialDict = new Dictionary<string, object>(); 
foo(serialDict); 

は今、私はConcurrentDictionaryタイプでfooを呼び出す必要があります。

var concurrentDict = new Dictionary<string, object>(); 
foo(concurrentDict); 

ConcurrentDictionaryIDictionaryを実装しているので、私はfooメソッドのシグネチャを変更する必要はありません。そして、変更は私のマシン上で正常に動作するようです。

しかし、同じ方法/方法で正規の辞書と並行して辞書を作成することができないということは、私にはうまくいきません。

安全なことは何ですか?

+0

なぜそれがOKでないのか分かりません。 Concurrent Dictによると、IDictionaryはどこでも使用できます。つまり、そのインタフェースを実装することで可能です。 – pm100

+3

どのような操作の下で「安全」ですか?あなたのプログラムは、それらのキーをあるスレッドに追加し、別のスレッドでそれらから読み込みますか?あなたは、読者が作家の後で実行するように注文する必要がありますか?それらの不変量はあなたのコードによって維持されていないからです。コンカレントディクショナリ**は競合状態でプロセスをクラッシュさせることはありません**しかし、それはあなたのプログラムが自動的に正しい*ことを意味するものではありません!辞書を静かに保つコードを書いていない限り、*常に変化する*として辞書を扱う必要があります。 –

+0

@EricLippert同じキーではなく、注文手順があります。他のスレッドはキーを追加または編集しますが、このメソッドではキーを追加または編集しません。 – AngryHacker

答えて

1

これは、インデックス作成操作を使用して辞書を変更するだけでは、インデックス作成のセマンティクスが追加または更新され、辞書がスレッドセーフで行う必要があるため、方法。 メソッドがキーの存在をチェックし、存在しない場合は値を追加するなどの複雑な処理を行うと、複数のスレッドが辞書に書き込んでいる場合に予期しない結果になることがあります(ConcurrentDictionaryはadd

辞書に追加して辞書から値を読み込み、別のスレッドが同じキーを変更すると、あなたの方法も混乱することがあります。

したがって、短い答えは一般的にはうまくいくはずですが、メソッドがスレッドの安全性を考慮して作成されていない場合は、並行処理の問題を分析する必要があります。

関連する問題