我刚刚开始了解一些新的 .NET 并发集合,例如 ConcurrentDictionary 和 ConcurrentQueue,并且我正在运行一些测试以查看当我对队列进行并行写入时会发生什么。
所以我运行了这个:
private static void ParallelWriteToQueue(Queue<int> queue)
{
Stopwatch sw = Stopwatch.StartNew();
Parallel.For(1,1000001,(i) => queue.Enqueue(i));
sw.Stop();
Console.WriteLine("Regular int Queue - " + queue.Count + " time" + sw.ElapsedMilliseconds);
}
我以为我得到了下一个异常(exception):
Source array was not long enough. Check srcIndex and length, and the array's lower bounds.
所以这个队列不能像预期的那样处理并发入队。
但是,当我把队列的类型改成string的时候,没有异常,结果是这样写的
Regular string Queue - 663209 time117
这意味着只有大约 663k 排队。
为什么没有异常(exception)?
所有未排队的项目发生了什么?
这与队列的功能相同
private static void ParallelWriteToQueue(Queue<string> queue)
{
Stopwatch sw = Stopwatch.StartNew();
Parallel.For(1, 100001, (i) => queue.Enqueue(i.ToString()));
sw.Stop();
Console.WriteLine("Regular string Queue - " + queue.Count + " time" + +sw.ElapsedMilliseconds);
}
最佳答案
Queue<T>
而不是 ConcurrentQueue<T>
根据 MSDN,它不是线程安全的。您描述的其他行为偶然发生于并发(多线程)写入访问引起的冲突,完全基于事实 Queue<T>
不是线程安全的。
关于c# - 并发下的 Queue<T> 为不同的类型提供不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11981659/