【问题标题】:Concurrent Dictionary AddOrUpdate vs Index Add并发字典 AddOrUpdate 与索引添加
【发布时间】:2013-07-29 14:22:10
【问题描述】:

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

A. concurrentDictionary1[key] = value;

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

如果我知道“密钥”存在,它们在功能上是否等效?

并发字典的并发提供的保护是否被方法'A'绕过了?

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

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

【问题讨论】:

  • 附带说明,I found these benchmarks 比较了多线程环境中更新值的速度。大多数情况下,带有锁定功能的常规字典胜过 ConcurrentDictionary。

标签: c#


【解决方案1】:

这是一个老问题,但没有人回答你为什么要使用一个而不是另一个。

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

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

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

【讨论】:

    【解决方案2】:

    他们都调用TryAddInternal,所以行为完全相同**。

    更新:

    还有一个区别。这是索引器中的代码:

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

    对比从方法上

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

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

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

    **我发疯了。

    【讨论】:

    • 如果键不存在,这个concurrentDictionary1[key] = value 不会抛出异常,而是将它添加到字典中。
    • 这是我的担心,索引器似乎很适合初始化,但在实际需要并发的地方可能会出人意料。
    • 你说的不完全正确。如果您只想无条件地添加或更新值,实际索引将完成它的工作。 AddOrUpdate() 应该在你想根据现有值更新值时使用,这就是为什么这个方法使用while 来确保你在updateFactory 中获得最实际的值(因此可能会被多次调用)。
    • 我认为您使用其中一个取决于您是否需要查看现有值。如果我只是在不关心现有值的情况下尝试添加,那么 IMO 使用 AddOrUpdate 没有任何意义。
    【解决方案3】:

    如果我知道“密钥”存在,它们在功能上是否等效?

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

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

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 如果键不存在,方法A不会抛出异常,而是将其添加到字典中。
      • 哦,是的,我把它和普通字典混在一起了。
      • 这也是普通字典的正常行为。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-23
      • 2013-06-21
      • 2023-03-16
      • 1970-01-01
      相关资源
      最近更新 更多