将数据从一个 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左右,反正。)
用睡眠模拟工作是一个常见的错误。
我有一个代码,将整数复制到缓冲区 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左右,反正。)
用睡眠模拟工作是一个常见的错误。