Я использую BlockingCollection
для реализации шаблона производителя/потребителя. У меня есть асинхронный цикл, который заполняет коллекцию данными, которые будут обработаны, которые затем могут быть доступны клиенту в гораздо более позднее время. Пакеты появляются редко, и я хотел бы, чтобы опрос был выполнен без использования блокирующего вызова.
В сущности, я ищу что-то вроде BeginTake
и EndTake
, которого нет в блокирующей коллекции, чтобы я мог использовать внутренний пул потоков в обратном вызове. Он не должен быть BlockingCollection
любым способом. Все, что делает то, что мне нужно, было бы здорово.
Это то, что у меня есть сейчас. _bufferedPackets
является BlockingCollection<byte[]>
:
public byte[] Read(int timeout)
{
byte[] result;
if (_bufferedPackets.IsCompleted)
{
throw new Exception("Out of packets");
}
_bufferedPackets.TryTake(out result, timeout);
return result;
}
Я хотел бы, чтобы это было что-то вроде этого, в псевдокоде:
public void Read(int timeout)
{
_bufferedPackets.BeginTake(result =>
{
var bytes = _bufferedPackets.EndTake(result);
// Process the bytes, or the resuting timeout
}, timeout, _bufferedPackets);
}
Каковы мои варианты для этого? Я не хочу помещать поток any в состояние ожидания, так как для него есть много других компонентов ввода-вывода, и я бы быстро закончил потоки.
Обновление: Я переписал рассматриваемый код, чтобы использовать процесс async по-другому, по существу, заменяя обратные вызовы на основе того, есть ли запрос ожидания в пределах тайм-аута. Это прекрасно работает, но все равно было бы здорово, если бы был способ сделать это, не прибегая к таймерам и заменяя лямбды вокруг, что потенциально вызывает расовые условия и трудно писать (и понимать). Я решил это также с собственной реализацией очереди async, но все равно было бы здорово, если бы был более стандартный и хорошо протестированный вариант.