34

現在のプロジェクトで並行辞書の既存のキーに値を割り当てる方法は 2 つあります。

A concurrentDictionary1[key] = value.;

B.concurrentDictionary2.AddOrUpdate(key, value, (k, v) => value);

「キー」が存在することがわかっている場合、これらは機能的に同等ですか?

メソッド 'A' でバイパスされたコンカレント ディクショナリの同時実行によって提供される保護はありますか?

ここでの違いは何ですか?どちらかを選択する理由は何ですか?

msdn のドキュメントを調べたところ、メソッド 'A' で同時実行辞書を初期化するだけで、更新はしていないようです。

4

4 に答える 4

31

これは古い質問ですが、なぜ一方を他方よりも優先して使用するのか、誰も答えていません。

追加または更新する必要があり、更新が既存の値に依存しない場合は、A (インデクサー) を選択します。

追加または更新する必要があり、更新が既存の値に依存する場合は、B (AddOrUpdate) を選択します。AddOrUpdate は更新をアトミックに行います。

したがって、質問の場合、インデクサーを使用したいと考えています。匿名関数を作成していないため、よりシンプルで読みやすく、おそらく高速です。

于 2014-05-30T18:56:01.010 に答える
16

どちらも を呼び出すTryAddInternalため、まったく同じように動作します**。

アップデート:

別の違いがあります。インデクサーのコードは次のとおりです。

set
{
    TValue tValue;
    if (key == null)
    {
        throw new ArgumentNullException("key");
    }
    this.TryAddInternal(key, value, true, true, out tValue);
}

vs. メソッドから

while (!this.TryAddInternal(key, tValue, false, true, out tValue1));

そのため、メソッドは成功するまで試行を続けますが、インデクサーがサイレントに失敗する可能性があるようです。うーん、2つの違いを完全に理解するには、さらに詳細な分析が必要です:/

逆コンパイラは今でもあなたの味方です。

**私はだまされました。

于 2013-07-29T14:30:03.267 に答える
3

「キー」が存在することがわかっている場合、これらは機能的に同等ですか?

あなたがそれを使用している方法、はい。実際、それらは存在するかどうかに関係なく同等ですkey

どちらかを選択する理由は何ですか?

AddOrUpdate値を更新するために使用される関数を受け入れます。値を直接設定するために使用しているだけですが、関数の結果に基づいて並行して値を更新するために使用するように設計されています。例えば:

concurrentDictionary2.AddOrUpdate(key, value, (k, v) => v + value);  // adds value to the existing value
于 2013-07-29T14:37:30.450 に答える
0

はい同等。いいえ。インデクサーは実際にはメソッド (プロパティと同様) であり、そのために同時実行性をバイパスするとは思いません。方法

于 2013-07-29T14:27:35.857 に答える