简体   繁体   English

标准线程安全.Net字典

[英]Standard Thread safe .Net Dictionary

MSDN points out that mutating access to the .NET Dictionary<K,V> type is not thread safe. MSDN指出,更改对.NET Dictionary<K,V>类型的访问权限不是线程安全的。 Is there a standard thread safe version? 有标准的线程安全版本吗?

Note: "No there is not" is a valid answer if it is true. 注意: “没有就没有”是正确的答案。 In that cases (and it seem to be) I'll go off and do the lock thing. 在那种情况下(看来是这样),我会去做锁事情。


Almost Duplicate 几乎重复

What's the best way of implementing a thread-safe Dictionary in .NET? 在.NET中实现线程安全字典的最佳方法是什么? (Not exact because I want a standard type, not something I implement my self) (不完全是因为我想要一个标准类型,而不是我实现自己的东西)

There isn't. 没有。 Consider this code, where each method/property was thread safe 考虑一下此代码,其中每个方法/属性都是线程安全的

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

athough each action could be threadsafe, the block of code has a race condition, b/c there are two method calls and two different critical sections. 尽管每个动作都可能是线程安全的,但是代码块具有竞争条件,b / c有两个方法调用和两个不同的关键部分。 The only way to do it is by hand 唯一的方法是手工

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

While Hashtable is not generic, it is thread-safe so long as you use it right (one writer, multiple readers, no enumeration). 尽管Hashtable不是通用的,但只要您正确使用它(一个写入器,多个读取器,没有枚举),它就具有线程安全性。

Thread Safety 线程安全

To support one or more writers, all operations on the Hashtable must be done through the wrapper returned by the Synchronized method. 为了支持一个或多个编写器,必须通过Synchronized方法返回的包装器对Hashtable进行所有操作。

Enumerating through a collection is intrinsically not a thread-safe procedure. 通过集合进行枚举本质上不是线程安全的过程。 Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. 即使同步了一个集合,其他线程仍然可以修改该集合,这将导致枚举器引发异常。 To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads. 为了保证枚举期间的线程安全,您可以在整个枚举期间锁定集合,也可以捕获由其他线程进行的更改导致的异常。

It is different than a Dictionary<K, V> though -- it will return null , not throw a KeyNotFoundException if you try to get a value that doesn't exist (so storing null values can be problematic). 但是它与Dictionary<K, V>有所不同-如果您尝试获取不存在的值,它将返回null ,而不抛出KeyNotFoundException (因此存储null值可能会出现问题)。 It's a very useful collection if you know you'll never have more than one thread trying to add a new key, and can deal with the null issue. 如果您知道尝试添加新密钥的线程永远不会超过一个,并且可以处理null问题,那么这是一个非常有用的集合。

.NET 4.0 now has a ConcurrentDictionary<K,T> class that seems to do what you want. .NET 4.0现在具有ConcurrentDictionary<K,T>类,该类似乎可以满足您的要求。 Also in .NET 4.5 也在.NET 4.5中

In addition to the answer of the duplicate question, you might want to take a look at this implementation that uses ReaderWriterSlim . 除了重复问题的答案外,您可能还想看一下使用ReaderWriterSlim实现 ReaderWriterSlim ought to infact offer some performance benefits over simple locking (which effectively uses Monitor ) - definitely take a look. ReaderWriterSlim应该比简单的锁定(有效使用Monitor )提供一些性能上的好处-一定要看看。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM