假设我有以下代码:
ConcurrentDictionary<long, long> myDict= new ConcurrentDictionary<long, long>();
通常,每个按键访问都是线程安全的,但也是以下linq查询线程安全? 我在文档中没有找到任何内容: http://msdn.microsoft.com/en-us/library/dd287226.aspx
if myDict.Values.Any(x => !x.HasPaid))
{
return false
}
答案 0 :(得分:38)
更正...我不确定您何时访问Values属性。在对象本身上使用LINQ时,它是线程安全的。
LINQ将使用GetEnumerator方法来迭代项目。
直接来自MSDN
从字典返回的枚举器可以安全地与字典的读写一起使用,但它并不代表字典的即时快照。通过枚举器公开的内容可能包含在调用GetEnumerator后对字典进行的修改
if myDict.Any(x => !x.Value.HasPaid))
{
return false
}
答案 1 :(得分:35)
如前所述,ConcurrentDictionary.GetEnumerator()不代表字典的时刻快照。但是,ConcurrentDictionary.Values确实生成了一个时刻快照。
因此以下内容并不等同:
myDict.Any(x => !x.Value.HasPaid)
myDict.Values.Any(x => !x.HasPaid)
答案 2 :(得分:10)
ConcurrentDictionary的文档声明(MSDN):
ConcurrentDictionary的所有公共成员和受保护成员都是线程安全的,可以从多个线程同时使用。
由于.Values属性是IColletion接口规定的实现,因此它是公共的,因此是线程安全的。
答案 3 :(得分:4)
到目前为止,所有的答案都很棒,很有帮助,但我认为DuneCat在其中一条评论中指出的链接强调:
具体.....
<强>无锁:强>
取出每一个锁(锁定?):