【问题标题】:How do you set a value in a ConcurrentDictionary regardless of whether it contains the Key如何在 ConcurrentDictionary 中设置值,无论它是否包含 Key
【发布时间】:2014-03-02 08:02:37
【问题描述】:

首先,使用索引分配(例如myConcurrentDictionary[someKey] = someValue;)将项目简单地添加到并发字典中是否安全?

我只是感到困惑,因为它隐藏了 IDictionary 方法(例如 Add)。

为什么 AddOrUpdate() 需要一个函数来更新值?有没有一种方法可以设置一个键的值而不管键是否已经存在?

我真的无法从 MSDN 页面收集到这个。

【问题讨论】:

  • 您所说的“安全”究竟是什么意思?
  • 现在对我自己来说,只要两个线程同时尝试添加/更新一个条目时没有异常是安全的。但是,实际上我提到了“安全”,因为我不明白 Add() 方法被隐藏的原因。所以我认为不应使用 Add() 或 []。
  • 所以您认为不应使用 both 成员,因为其中只有 一个 被显式实现?我不明白这其中的逻辑。如果您不打算使用索引器,那也会显式实现。
  • 是的,我知道,只是觉得这样问更安全。

标签: c# concurrentdictionary


【解决方案1】:
  1. 是的,如果你想添加或替换一个值,使用索引器应该是绝对没问题的。

  2. AddOrUpdate 接受一个委托,以便您可以将“旧”和“新”值合并在一起以形成您希望在字典中出现的值。如果您不关心旧值,请改用索引器。

  3. 索引器“为键设置值而不管键是否已存在”的方式,就像在任何其他IDictionary<,> 实现中一样。

documentation 在底部有一个整洁的部分 - 一种配方位 - 包括:

为此...
无条件地在字典中存储一个键/值对,并覆盖一个已经存在的键的值

使用此方法
索引器的设置器:dictionary[key] = newValue

所以它得到了官方的认可。

【讨论】:

    【解决方案2】:

    索引器将找到给定键表示的对,如果不存在则添加它,如果存在则用给定值替换该值。从字典的角度来看,这个操作在逻辑上是“原子的”。当多个线程通过其索引器同时访问字典时,您无需担心字典被损坏。

    Add 是隐藏的,因为您通常应该改用TryAdd。如果在检查密钥是否存在后由另一个线程添加该密钥,则添加可能会失败。这当然不是索引器的问题。如果另一个线程在当前线程之前添加了该项目,它只会覆盖该值,而不是抛出异常。

    AddOrUpdated 采用函数进行更新有两个原因:

    1. 它可以使用以前的值来确定更新的值。
    2. 生成更新的值可能会产生副作用,或者是昂贵的计算。将其设置为函数可以推迟此操作,直到您知道确实需要更新项目为止。

    【讨论】:

      猜你喜欢
      • 2013-12-17
      • 1970-01-01
      • 1970-01-01
      • 2011-01-06
      • 1970-01-01
      • 1970-01-01
      • 2012-09-28
      • 2020-06-28
      • 2022-07-05
      相关资源
      最近更新 更多