System.Collections.Concurrent имеет несколько новых коллекций, которые очень хорошо работают в многопоточных средах. Однако они немного ограничены. Либо они блокируются, пока элемент становится доступным, либо они возвращают default(T)
(методы TryXXX).Неблокирующий параллельный сбор?
Мне нужна коллекция, которая является потокобезопасной, но вместо блокировки вызывающего потока он использует обратный вызов, чтобы сообщить мне, что доступен хотя бы один элемент.
Мое настоящее решение - использовать BlockingCollection, но использовать APM с делегатом для получения следующего элемента. Другими словами, я создаю делегата для метода, который Take
s из коллекции, и выполняет этот делегат с использованием BeginInvoke
.
К сожалению, я должен поддерживать много состояний в своем классе, чтобы выполнить это. Хуже того, класс не является потокобезопасным; он может использоваться только одним потоком. Я обойду край ремонтопригодности, который я бы предпочел не делать.
Я знаю, что есть некоторые библиотеки, которые делают то, что я делаю здесь довольно просто (я считаю, что Reactive Framework является одним из них), но я хотел бы достичь своих целей, не добавляя никаких ссылок за пределы версии 4 рамок.
Есть ли лучшие шаблоны, которые я могу использовать, которые не требуют внешних ссылок, которые достигают моей цели?
Т.Л., д-р:
Существует ли какая-либо модель, удовлетворяющие требования:
«Мне нужно, чтобы сигнализировать коллекцию, я готов к следующему элементу, и есть коллекция выполнить обратный вызов, когда этот следующий элемент прибыл, без блокировки нитей ».
Будет ли это быть потокобезопасным? Что останавливает доступный предмет, недоступный до вызова делегата? И какова ваша общая цель (т. Е. Система очередей)? –
@Adam Хорошая точка в потреблении товара. Делегат берет предмет, удаленный из коллекции. Таким образом, выполнение делегата блокируется до тех пор, пока элемент не будет 'Take'-en из коллекции, и этот элемент является« объектом », переданным EndInvoke. Общая цель немного запутана; по существу я должен простаивать рабочий процесс, пока элемент не станет доступен. Вы не можете заблокировать выполнение рабочего процесса, поэтому просто «Take'-ing item не будет работать как блоки вызовов. Мне нужно создать закладку, а затем передать это расширение. Расширение вызывает делегата, возобновляя закладку в обратном вызове. – Will
К сожалению, у меня мало опыта работы с рабочими процессами - попробуйте добавить эту деталь к своему вопросу, и это может вызвать интерес человека :-) –