我的工作假设是,当与System.Collections.Concurrent集合(包括ConcurrentDictionary)一起使用时,LINQ是线程安全的.
(其他Overflow帖子似乎同意:链接)
但是,对LINQ OrderBy扩展方法的实现的检查表明,对于实现ICollection的并发集合的子集(例如ConcurrentDictionary),它似乎不是线程安全的.
所述OrderedEnumerable 的GetEnumerator(源此处)构造一个实例缓冲结构(源这里它试图收集强制转换为)的ICollection(其ConcurrentDictionary实现),然后用初始化为集合的大小的阵列执行collection.CopyTo.
因此,如果在OrderBy操作期间ConcurrentDictionary(在这种情况下为具体的ICollection)的大小增加,在初始化数组和复制到它之间,此操作将抛出.
以下测试代码显示此异常:
(注意:我很欣赏在一个线程安全的集合上执行一个OrderBy,这个集合在你下面发生变化并没有那么有意义,但我不相信它应该抛出)
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Program
{
class Program
{
static void Main(string[] args)
{
try
{
int loop = 0;
while (true) //Run many loops until exception thrown
{
Console.WriteLine($"Loop: {++loop}");
_DoConcurrentDictionaryWork().Wait();
}
}
catch …Run Code Online (Sandbox Code Playgroud)