c# - 并发下的 Queue<T> 为不同的类型提供不同的结果

标签 c# .net collections concurrency

我刚刚开始了解一些新的 .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/

相关文章:

c# - 与google prediction API 具有相似功能的.Net 库

java - 有没有办法将列表中的所有内部对象提取到新列表

java - Collections中的synchronizedMap方法是否同步读写操作

c# - <> 转换为 64BaseString 和从 64BaseString 时 Xml 丢失

c# - JSON 数据无法在 jQuery 中正确序列化

c# - 查看模型和依赖注入(inject)

Java集合以键值对的形式存储多种类型的数据

c# - 计算两个计时器值之间的平均值

c# - 用户确认删除先前版本

c# - EF4 - Context.Entry 不可用于更改实体状态