Microsoft недавно отказалась от System.Threading.Channels
, который предназначен для предоставления оптимизированных API производителей / потребителей, что может хорошо подойти в этом случае.Он охватывает неограниченные и ограниченные сценарии и включает в себя сценарии «один плюс несколько читателей / писателей».API довольно прост и интуитивно понятен в использовании;Единственное небольшое предостережение заключается в том, что он использует async
-ориентированный API (для потребителя и - в случае ограниченных каналов - для производителя).
Дело здесь в том, что код, который вы не 'Как правило, писать - это код, в котором меньше болевых точек, особенно если он написан командой, обладающей опытом и заинтересованностью в решении конкретных проблем.
Однако: вы можете делать все в своем текущем кодебез необходимости ManualResetEvent
- lock
в C # - это просто оболочка для простейших частей Monitor
, но Monitor
также обеспечивает функцию ожидания / импульса:
class ProducerConsumerQueue<T>
{
private readonly Queue<T> Queue = new Queue<T>();
public void Add(T t)
{
lock (Queue)
{
Queue.Enqueue(t);
if (Queue.Count == 1)
{
// wake up one sleeper
Monitor.Pulse(Queue);
}
}
}
public bool TryTake(out T t, int millisecondsTimeout)
{
lock (Queue)
{
if (Queue.Count == 0)
{
// try and wait for arrival
Monitor.Wait(Queue, millisecondsTimeout);
}
if (Queue.Count != 0)
{
t = Queue.Dequeue();
return true;
}
}
t = default(T);
return false;
}
}