34

在我当前的项目中,我有两种方法为并发字典中的现有键分配值。

一个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));

因此,索引器似乎有可能静默失败,而该方法将继续尝试直到成功。嗯,需要更深入的分析才能完全理解两者之间的差异:/

反编译器仍然是你的朋友。

**我发疯了。

于 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 回答