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

时间:2015-02-25 16:59:12

标签: task c#-5.0 producer-consumer

我有一个代码,它将整数复制到buffer1,然后从buffer1复制到buffer2,然后从buffer2中获取所有数据。 它在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毫秒放在那里,因为它的数量很少。我无法相信删除它会使代码几乎立即完成。

1 个答案:

答案 0 :(得分:1)

时钟的分辨率约为15ms。 1ms被四舍五入到15.这就是为什么1000个项目需要大约15秒。 (实际上,我很惊讶。平均每次等待大约需要7.5毫秒。无论如何。)

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