是一个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在其中一个评论中指出的链接强调:
特别…..
无锁:
- TryGetValue
- 的GetEnumerator
- 索引器getter
- 的containsKey
取出每个锁(lockfull?):
- 计数
- 是空的
- 按键
- 值
- 复制到
- ToArray的