Как правильно взять элемент из коллекции BlockingCollection? - PullRequest
14 голосов
/ 18 августа 2011

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

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

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

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

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

1 Ответ

14 голосов
/ 18 августа 2011

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

...