是一个linq查询ConcurrentDictionary值线程安全吗?

让我们说我有以下代码:

ConcurrentDictionary<long, long> myDict= new ConcurrentDictionary<long, long>(); 

通常每个按键的访问都是线程安全的,但也是以下linq查询线程安全? 我还没有在文档中find任何内容: http : //msdn.microsoft.com/en-us/library/dd287226.aspx

 if myDict.Values.Any(x => !x.HasPaid)) { return false } 

更正…我不确定何时访问Values属性。 在对象上使用LINQ时,它是线程安全的。


LINQ将使用GetEnumerator方法来遍历项目。

直接从MSDN

从字典返回的枚举器可以安全地同时使用对字典的读写操作,但是它并不代表字典的即时快照(instant-in-time snapshot)。 通过枚举器公开的内容可能包含调用GetEnumerator后对字典所做的修改

 if myDict.Any(x => !x.Value.HasPaid)) { return false } 

如前所述,ConcurrentDictionary.GetEnumerator()不代表字典的即时快照。 但是,ConcurrentDictionary.Values确实会产生一个瞬间快照。

因此以下几点不相同:

 myDict.Any(x => !x.Value.HasPaid) myDict.Values.Any(x => !x.HasPaid) 

ConcurrentDictionary的文档指出:

ConcurrentDictionary的所有公共和受保护成员都是线程安全的,可以从多个线程同时使用。

由于.Values属性是由IColletion接口指定的实现,因此它是公共的,因此是线程安全的。

到目前为止所有的答案都是非常有用的,但我认为DuneCat在其中一个评论中指出的链接强调:

http://geekswithblogs.net/simonc/archive/2012/02/22/inside-the-concurrent-collections-concurrentdictionary.aspx

特别…..

无锁:

  • TryGetValue
  • 的GetEnumerator
  • 索引器getter
  • 的containsKey

取出每个锁(lockfull?):

  • 计数
  • 是空的
  • 按键
  • 复制到
  • ToArray的