即使队列为空,queue.IsCompleted也返回false?

时间:2016-05-16 17:55:50

标签: c# task-parallel-library blockingqueue

以下代码永远不会返回。调试显示即使队列为空,queue.IsCompleted也返回false。我错过了什么吗?

var workers = new Task[1];
using (var queue = new BlockingCollection<QueuePayload>(20))
{
    workers[0] = Task.Run(() => Consume(queue));
    queue.Add(new QueuePayload{....});
    Task.WaitAll(workers);
}

void Consume(BlockingCollection<QueuePayload> queue))
{
    while (!queue.IsCompleted)
    {
        var i = new QueuePayload();
        try
        {
            i = queue.Take();
        }
        catch (InvalidOperationException)
        {
            break;
        }
    ......

2 个答案:

答案 0 :(得分:3)

https://msdn.microsoft.com/en-us/library/dd267315(v=vs.110).aspx IsCompleted的媒体资源包含以下文字:

  

此集合是否已标记为已完成添加且为空。

您在哪里将该系列标记为已完成?这不是一个空的检查 - 它是一个带有手动附加开关的空检查。

因此有CompleteAdding()方法标记不再添加任何项目。

答案 1 :(得分:1)

完成向集合中添加项目后,请致电queue.CompleteAdding()。这样,queue.IsCompleted将在集合中没有项目时返回true(在您删除所有项目之后)。如果您没有拨打CompleteAdding(),那么可能会有更多项目可能添加后,IsCompleted将始终返回false