Is Concurrent Collections are thread safe when we use them in linq queries? and what is the difference between Concurrent Collection and Immutable Collections??
2 回答
所有 linq 方法都通过 IEnumerable 工作,因此它们使用 GetEnumerator 方法的实现。从 ConcurrentDictionary 的源代码中,我可以看到微软关于 GetEnumerator 实现的评论:
从字典返回的枚举器可以安全地与字典的读取和写入同时使用,但它并不代表字典的即时快照。通过枚举器公开的内容可能包含调用后对字典所做的修改。
这意味着您可以枚举 ConcurrentDictionary 但它可能会在枚举期间被其他线程修改,因此您可以获得部分更新的字典作为枚举的结果。为了防止这种情况,您可以通过在枚举之前调用 dict.ToArray 或使用 dict.Keys 或 dict.Values 来获取字典的快照 - 它们在内部获取快照。
ConcurrentStack、ConcurrentQueue 和 ConcurrentBag 的工作方式不同:
枚举表示堆栈内容的即时快照。它不反映调用后对集合的任何更新。枚举器可以安全地与堆栈的读取和写入同时使用。
这意味着当您开始迭代时,您将获得当前堆栈/队列的快照,因此其他线程无法更改它。
至于 Concurrent 和 Immutable 集合之间的区别,Ariex answer 给了你一个很好的解释。
据我了解,不可变集合意味着您只能读取其值但不能更改它们,这在并发场景中可以正常工作,因为只有所有读取。并发集合类似于不可变集合,但为您提供了更多功能以允许您对其进行编辑。不可变集合自然是线程安全的,并发集合是线程安全的