-1

我试图确定为什么我的阻塞集合的性能看起来很慢。下面的问题进一步说明了我的代码的简单版本。

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

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

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

从我的测试看来,数据不会立即返回。这似乎是理想的行为还是我使用不正确?

上一个问题的代码细节:

使用 BlockingCollection 的消费者/生产者看起来很慢

4

1 回答 1

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

于 2014-07-14T10:20:24.890 回答