Страницы

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

воскресенье, 22 декабря 2019 г.

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

#c_sharp #многопоточность #коллекции #очередь


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

P.S. Есть метод TryTake, но я не могу найти решение с его использованием, эквивалентное
использованию Take и при этом неблокирующее поток.
    


Ответы

Ответ 1



Вам на самом деле нужен класс BufferBlock из библиотеки Dataflow (nuget-пакет Microsoft.Tpl.Dataflow). Этот класс заменяет собой BlockingCollection, и позволяет асинхронный доступ: await queue.ReceiveAsync() Таким образом, поток не будет заблокирован. Но у вас получится async-интерфейс. Больше примеров с работающим кодом есть в этом ответе. Ещё одним вариантом является async-обёртка над IProducerCosumerCollection из AsyncEx Стивена Клири: https://github.com/StephenCleary/AsyncEx/wiki/AsyncCollection

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

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