BlockingCollection.TryTake(object,TimeSpan)应该立即返回新数据吗?

时间:2014-07-14 10:00:22

标签: c# performance blockingcollection

我试图确定为什么我的阻止集合上的性能显得很慢。我的代码的简单版本在下面的问题中说明。

我的问题是,如果BlockingCollection.TryTake(object,TimeSpan)立即返回新数据?

TimeSpan gridNextTS = new TimeSpan(0, 0, 60);

if (trPipe.TryTake(out tr, gridNextTS) == false)

从我的测试中看来,数据不会立即返回。这似乎是可能需要的行为,还是我错误地使用它?

代码详情上一个问题:

Consumer/Producer with BlockingCollection appears slow

1 个答案:

答案 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}}之前。