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