我试图确定为什么我的阻止集合上的性能显得很慢。我的代码的简单版本在下面的问题中说明。
我的问题是,如果BlockingCollection.TryTake(object,TimeSpan)立即返回新数据?
TimeSpan gridNextTS = new TimeSpan(0, 0, 60);
if (trPipe.TryTake(out tr, gridNextTS) == false)
从我的测试中看来,数据不会立即返回。这似乎是可能需要的行为,还是我错误地使用它?
代码详情上一个问题:
答案 0 :(得分:4)
简洁的基准测试显示,BlockingCollection<T>
实际上非常快速地执行切换,无论提供给TryTake
的超时值如何。
public async Task BlockingCollectionPerformance()
{
using (var collection = new BlockingCollection<int>())
{
var consumer = Task.Run(() =>
{
var i = 0;
while (collection.TryTake(out i, TimeSpan.FromSeconds(2)))
{
Debug.Print(i.ToString());
}
});
var producer = Task.Run(() =>
{
try
{
for (var i = 0; i < 10; i++)
{
collection.Add(i);
}
}
finally
{
collection.CompleteAdding();
}
});
await Task.WhenAll(producer, consumer);
}
}
上面的内容在我的盒子上大约3毫秒完成。
更具体地说,只要项目被添加到集合中,TryTake
就会快速返回(并且TryTake
返回true
),或阻塞集合上的CompleteAdding
(在这种情况下等待超时没有意义,TryTake
返回false
)。如果你从不打电话CompleteAdding
TryTake
false
必须等待完整的超时长度,那么 可能会让消费者被阻止超过必要的时间。在返回{{1}}之前。