并发字典AddOrUpdate与索引添加

时间:2013-07-29 14:22:11

标签: c#

我有两种方法可以为当前项目中的并发字典中的现有键指定值。

一个。 concurrentDictionary1[key] = value;

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

如果我知道“钥匙”存在,这些功能是否相同?

并发字典的并发性提供的保护是否被方法“A”绕过?

这有什么区别?选择其中一个的原因是什么?

我查看了msdn上的文档,似乎他们只使用方法'A'初始化并发字典,而不是更新它。

4 个答案:

答案 0 :(得分:19)

这是一个古老的问题,但没有人回答为什么你会使用其中一个。

如果要添加或更新,请选择A(索引器),并且更新不依赖于现有值。

如果要添加或更新,请选择B(AddOrUpdate),并且更新取决于现有值。 AddOrUpdate将以原子方式进行更新。

因此,在问题的情况下,您想要使用索引器。它更简单,更容易阅读,并且可能更快,因为您没有创建匿名函数。

答案 1 :(得分:11)

他们都叫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 :(得分:3)

  

如果我知道“钥匙”存在,这些功能是否相同?

你使用它的方式,是的。事实上,无论key是否存在,它们都是等价的。

  

选择其中一个的原因是什么?

AddOrUpdate接受函数用于更新值。您只是使用它来直接设置值,但它被设计用于根据函数的结果以并发方式更新值。例如:

concurrentDictionary2.AddOrUpdate(key, value, (k, v) => v + value);  // adds value to the existing value

答案 3 :(得分:0)

是等效的。 编号索引器实际上是方法(就像属性一样),我认为它们不会绕过并发性。 方法