2016-05-16 3 views
1

Следующий код никогда не возвращается. Отладка показывает, что queue.IsCompleted возвращает false, даже когда очередь пуста. Я что-то пропустил?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; 
     } 
    ...... 
+0

Вместо 'while (! Queue.IsCompleted) {i = queue.Take(); ... 'Я нахожу, что намного проще сделать просто' foreach (var i в queue.GetConsumingEnumerable()) {... ' –

+0

Итак, если вы добавите' queue.CompleteAdding() 'после последней' queue.Add (new QueuePayload {.....}) 'все еще ведет себя так? –

+0

Я следовал примерам в MSDN. Возможно, они должны обновить эти примеры. – ca9163d9

ответ

3

Свойство для IsCompleted в https://msdn.microsoft.com/en-us/library/dd267315(v=vs.110).aspx имеет следующий текст:

ли эта коллекция была помечено как полная для добавления и пуст.

Место, где вы пометили коллекцию как завершенный? Это не пустая проверка - это пустая проверка с помощью ручного дополнительного переключателя.

Существует, соответственно, метод CompleteAdding(), который отмечает, что больше не будет добавлено больше предметов.

+0

Не знаете, кто это отметил, но если вопрос о том, почему флаг IsCompleted не возвращает 'true', когда очередь пуста, он отвечает на этот вопрос. –

1

Когда вы закончите добавлять предметы в коллекцию, позвоните по телефону queue.CompleteAdding(). Таким образом, queue.IsCompleted вернет true, когда в коллекции нет предметов (после того, как вы их удалили.) Если вы не вызываете CompleteAdding(), тогда есть возможность добавления большего количества предметов, поэтому IsCompleted всегда будет возвращать false.