将数据从一个 BlockingCollection 移动到另一个

Moving data from one BlockingCollection to the other

我有一个代码,将整数复制到缓冲区 1,然后从缓冲区 1 复制到缓冲区 2,然后使用缓冲区 2 中的所有数据。 它在 15 秒内处理 1000 个值,与输入的大小相比,这是很多时间。当我从第二个任务 t2 中删除“ Task.Delay(1).Wait() ”时,它完成得非常快。 现在,我的问题是:速度变慢是因为两个线程争夺锁还是我的代码有问题?

        var source = Enumerable.Range(0, 1000).ToList();

        var buffer1 = new BlockingCollection<int>(100);
        var buffer2 = new BlockingCollection<int>(100);


        var t1 = Task.Run
        (
            delegate
            {
                foreach (var i in source)
                {
                    buffer1.Add(i);
                }

                buffer1.CompleteAdding();
            }
        ).ConfigureAwait(false);


        var t2 = Task.Run
        (
            delegate
            {
                foreach (var i in buffer1.GetConsumingEnumerable())
                {
                    buffer2.Add(i);
                    //Task.Delay(1).Wait();
                }

                buffer2.CompleteAdding();
            }
        ).ConfigureAwait(false);


        CollectionAssert.AreEqual(source.ToList(), buffer2.GetConsumingEnumerable().ToList());

更新:这只是一个演示代码,我阻塞 1 毫秒只是为了模拟在我的真实代码中发生的一些计算。我在那里放了 1 毫秒,因为它太小了。我不敢相信删除它会使代码几乎立即完成。

时钟的分辨率约为 15 毫秒。 1 毫秒四舍五入为 15。这就是为什么 1000 个项目需要大约 15 秒。 (其实我很惊讶,平均每次等待应该需要7.5ms左右,反正。)

用睡眠模拟工作是一个常见的错误。