Как очистить BlockingCollection - PullRequest
       11

Как очистить BlockingCollection

14 голосов
/ 04 ноября 2011

У меня есть нить, добавляющая элементы в BlockingCollection.

В другой теме я использую foreach (var item in myCollection.GetConsumingEnumerable())

Если есть проблема, я хочу вырваться из моего foreach и моего метода и очистить все, что осталось в BlockingCollection, однако я не могу найти способ сделать это.

Есть идеи?

Ответы [ 6 ]

16 голосов
/ 10 июля 2012

Я использую этот метод расширения:

public static void Clear<T>(this BlockingCollection<T> blockingCollection)
{
    if (blockingCollection == null)
    {
        throw new ArgumentNullException("blockingCollection");
    }

    while (blockingCollection.Count > 0)
    {
        T item;
        blockingCollection.TryTake(out item);
    }
}

Мне интересно, есть ли лучшее, менее хакерское решение.

6 голосов
/ 04 ноября 2011

Возможно использовать перегрузку GetConsumingEnumerable, которая занимает CancellationToken;затем, если что-то пойдет не так со стороны производителя, это может отменить потребителя.

5 голосов
/ 10 сентября 2014

Это сработало для меня

while (bCollection.Count > 0)
{
    var obj = bCollection.Take();
    obj.Dispose();
}

Take() удаляет из коллекции, и вы можете вызвать любую очистку вашего объекта, и условие цикла не вызывает никаких блокирующих вызовов.

2 голосов
/ 03 апреля 2018

Достаньте все оставшиеся предметы:

while (collection.TryTake(out _)){}
1 голос
/ 04 ноября 2011
BlockingCollection<T> yourBlockingCollection = new BlockingCollection<T>();

Я предположил, что вы имеете в виду очистить коллекцию блокировок.Я думаю, что ответ Джона больше соответствует вашему актуальному вопросу.

0 голосов
/ 10 января 2013

Для простой очистки коллекции вы можете сделать:

myBlockingCollection.TakeWhile<*MyObject*>(qItem => qItem != null);

или просто

myBlockingCollection.TakeWhile<*MyObject*>(qItem => true);
...