Страницы

Поиск по вопросам

вторник, 13 ноября 2018 г.

BlockingCollection - как не блокировать поток

Применение BlockingCollection, используя подход, когда элементы вытаскиваются из очереди(например ConcurrentQueue), используя метод Take в цикле - всегда блокирует поток. Очевидно, что процессорное время не занимается, однако поток все же занят и не может использоваться для выполнения других задач. Какая есть альтернатива, когда нужно последовательно вычитывать элементы из очереди и при этом не блокировать поток? Конечно, можно сделать велосипед, накрутить событий или чего-нибудь еще, но хотелось бы понять, нет ли каких-либо стандартных способов это сделать, кроме как использовать BlockingCollection и метод Take
P.S. Есть метод TryTake, но я не могу найти решение с его использованием, эквивалентное использованию Take и при этом неблокирующее поток.


Ответ

Вам на самом деле нужен класс BufferBlock из библиотеки Dataflow (nuget-пакет Microsoft.Tpl.Dataflow).
Этот класс заменяет собой BlockingCollection, и позволяет асинхронный доступ:
await queue.ReceiveAsync()
Таким образом, поток не будет заблокирован. Но у вас получится async-интерфейс.
Больше примеров с работающим кодом есть в этом ответе

Ещё одним вариантом является async-обёртка над IProducerCosumerCollection из AsyncEx Стивена Клири: https://github.com/StephenCleary/AsyncEx/wiki/AsyncCollection

Комментариев нет:

Отправить комментарий