Ответ 1
Возможно, используйте перегрузку GetConsumingEnumerable
которая принимает CancellationToken
, и затем, если что-то пойдет не так с производящей стороны, это может отменить потребителя.
У меня есть поток, добавляющий элементы в BlockingCollection
.
В другом потоке я использую
foreach (var item in myCollection.GetConsumingEnumerable())
Если есть проблема, я хочу вырваться из своего foreach и моего метода и очистить все, что осталось в BlockingCollection
, но я не могу найти способ сделать это.
Любые идеи?
Возможно, используйте перегрузку GetConsumingEnumerable
которая принимает CancellationToken
, и затем, если что-то пойдет не так с производящей стороны, это может отменить потребителя.
Я использую этот метод расширения:
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);
}
}
Мне интересно, есть ли лучшее, менее хакерское решение.
Это сработало для меня
while (bCollection.Count > 0)
{
var obj = bCollection.Take();
obj.Dispose();
}
Take()
удаляет из коллекции, и вы можете вызывать любую очистку вашего объекта, а условие цикла не вызывает никаких блокирующих вызовов.
Достаньте все оставшиеся предметы:
while (collection.TryTake(out _)){}
BlockingCollection<T> yourBlockingCollection = new BlockingCollection<T>();
Я предполагал, что вы имеете в виду очистить свою блокирующую коллекцию. Ответ Джона более уместен для вашего фактического вопроса, который я думаю.
Для простой очистки коллекции вы можете:
myBlockingCollection.TakeWhile<*MyObject*>(qItem => qItem != null);
или просто
myBlockingCollection.TakeWhile<*MyObject*>(qItem => true);