Каков правильный способ взять элемент из BlockingCollection?

При вызове BlockingCollection.Take() возможно, что статус IsCompleted коллекции изменится между проверкой IsCompleted и вызовом Take().

Документация MSDN, в которой показан пример, просто улавливает исключение недействительной операции, но похоже, что должен быть правильный способ сделать такой звоните, не перехватывая исключение (так как это несет приличный объем накладных расходов и не выглядит чистым в коде). Каким образом можно вызвать метод .Take() и избежать недопустимого исключения операции?

Упрощенная версия моей конкретной проблемы:

If (!blockingCollection.IsCompleted)
{
//do some stuff
value = blockingCollection.Take();  //Throws Exception, IsCompleted = True;
}

Существует доступный метод TryTake, но у меня создается впечатление, что он может быть передан токен времени ожидания и отмены, а не обрабатывать IsCompleted, становясь истинным, между временем его проверки и когда Take ( ) называется.

Ответ 1

Вы можете использовать перегрузку TryTake без тайм-аута/отмены. Он вернет false, если BlockingCollection пуст или был отмечен как завершенный, и обрабатывает проблему синхронизации, с которой вы столкнулись правильно.