【问题标题】:Standard Thread safe .Net Dictionary标准线程安全的 .Net 字典
【发布时间】:2010-10-24 22:27:51
【问题描述】:

MSDN 指出对 .NET Dictionary<K,V> 类型的变异访问不是线程安全的。有标准的线程安全版本吗?

注意:“不,没有”如果为真,则为有效答案。在那种情况下(而且看起来是这样),我会去做锁定的事情。


几乎重复

What’s the best way of implementing a thread-safe Dictionary in .NET?(不准确,因为我想要一个标准类型,而不是我自己实现的东西)

【问题讨论】:

  • 绝对没有标准类型。 BCL 没有为您提供一个,因为有许多不同的方法来实现线程安全(使用我建议的 ReaderWriterSlim,或者一个简单的锁,这可能就足够了)。我仍然认为这是完全重复的。

标签: .net multithreading dictionary


【解决方案1】:

.NET 4.0 现在有一个 ConcurrentDictionary<K,T> 类,它似乎可以满足您的需求。 Also in .NET 4.5

【讨论】:

    【解决方案2】:

    虽然Hashtable 不是通用的,但只要您正确使用它,它就是线程安全的(一个写入器,多个读取器,无枚举)。

    线程安全

    为了支持一位或多位作家,所有 Hashtable 上的操作必须是 通过返回的包装器完成 同步方法。

    通过集合枚举是 本质上不是线程安全的 程序。即使是一个集合 同步,其他线程可以 仍然修改集合,其中 导致枚举器抛出一个 例外。保证线程安全 在枚举期间,您可以 在整个过程中锁定集合 枚举或捕获异常 由其他人所做的更改导致 线程。

    但它与Dictionary<K, V> 不同——如果您尝试获取不存在的值,它将返回null,而不是抛出KeyNotFoundException(因此存储空值可能会出现问题)。如果您知道尝试添加新密钥的线程永远不会超过一个,并且可以处理 null 问题,那么这是一个非常有用的集合。

    【讨论】:

      【解决方案3】:

      没有。考虑这段代码,其中每个方法/属性都是线程安全的

      if (!SFdict.Contains(key))
      {
         SFdict[key] = value;
      }
      

      虽然每个动作都可以是线程安全的,但代码块有一个竞争条件,b/c 有两个方法调用和两个不同的临界区。唯一的办法就是手工

      lock(lck)
      {
         if (!dict.Contains(key))
         {
            dict[key] = value;
         }
      }
      

      【讨论】:

      • AddOrReturnOld 方法可以解决这个问题。此外,您的示例是一个很好的论据,说明为什么应该有标准类型来正确处理这些事情
      【解决方案4】:

      除了重复问题的答案之外,您可能还想看看this implementation that uses ReaderWriterSlimReaderWriterSlim 实际上应该比简单锁定(有效地使用 Monitor)提供一些性能优势 - 一定要看看。

      【讨论】:

      • @BCS:我认为答案应该从没有标准类型的副本中显而易见。这是您将得到的最好的。
      • 我会认为这个回答者是“否”,但回答者几乎重复的是代码,它们怎么可能是实际重复的?
      • @BCS:请参阅我对这个问题的评论。不管怎样,你现在有了答案。
      猜你喜欢
      • 2010-10-05
      • 1970-01-01
      • 1970-01-01
      • 2013-02-10
      • 1970-01-01
      • 2011-10-20
      • 2011-01-17
      • 1970-01-01
      相关资源
      最近更新 更多