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

237
20 декабря 2017, 19:20

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

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

Answer 1

Вам на самом деле нужен класс BufferBlock<T> из библиотеки Dataflow (nuget-пакет Microsoft.Tpl.Dataflow).

Этот класс заменяет собой BlockingCollection<T>, и позволяет асинхронный доступ:

await queue.ReceiveAsync()

Таким образом, поток не будет заблокирован. Но у вас получится async-интерфейс.

Больше примеров с работающим кодом есть в этом ответе.

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

READ ALSO
Теги в движке Unity3D

Теги в движке Unity3D

Можно ли на один игровой объект поставить два тега? Если можно, то как?

173
Не могу добавить DataSource в С#

Не могу добавить DataSource в С#

ПриветНе могу добавить DataSource в С# так как у меня нету этой кнопки

277
Создание экземпляров System.Web.UI.UserControl

Создание экземпляров System.Web.UI.UserControl

Задача создавать программно экземпляры объектов класса UserControl для заполнения ими таблицы GridView

226
Как вытащить конкретный кусок из строки

Как вытащить конкретный кусок из строки

Есть строка с именем файла(например string filename= FI_FILE1_111_1111)Как мне вытащить его префикс до второго нижнего подчеркивания(FI_FILE1_)??

166