一个简洁的基准测试表明,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。