并发收藏和Linq

时间:2015-02-17 06:06:20

标签: concurrent-collections immutablelist

当我们在linq查询中使用它们时,Concurrent Collections是否是线程安全的?并发收集和不可变集合之间的区别是什么?

2 个答案:

答案 0 :(得分:1)

根据我的理解,不可变集合意味着你只能读取它的值而不能更改它们,这在并发场景中可以正常工作,因为只有所有读取。 并发集合就像不可变集合,但为您提供了更多功能,允许您编辑它。 不可变集合自然是线程安全的,并且并发集合是线程安全的

答案 1 :(得分:0)

所有linq方法都通过IEnumerable工作,因此他们使用GetEnumerator方法的实现。从ConcurrentDictionary的源代码中我可以看到Microsoft关于GetEnumerator实现的注释:

  

从字典返回的枚举器可以安全地与之同时使用           读取和写入字典,但它不代表即时快照           字典。通过调查员公开的内容可能包含修改           在被召唤之后发给字典。

这意味着您可以枚举ConcurrentDictionary,但在枚举期间可能会被其他线程修改,因此您可以通过枚举获得部分更新的字典。为了防止这种情况,您可以通过在枚举之前调用dict.ToArray或使用dict.Keys或dict.Values来获取字典的快照 - 它们会在内部拍摄快照。

ConcurrentStack,ConcurrentQueue和ConcurrentBag的工作方式不同:

  

枚举表示内容的即时快照            堆栈。它不反映之后对集合的任何更新             被称为。调查员可以安全使用            与堆栈的读取和写入同时发生。

这意味着当您开始迭代时,您将获得当前堆栈/队列的快照,因此其他线程无法更改它。

至于Concurrent和Immutable集合之间的区别,Ariex的答案给你一个很好的解释。

相关问题