Ответ 1
Попробуйте очередь блокировки: Создание блокирующей очереди <T> в .NET?
Основная идея заключается в том, что при вызове TryDequeue
он будет блокироваться до тех пор, пока в очереди не появится что-то. Как вы видите, "красота" блокирующей очереди заключается в том, что вам не нужно опросить/спать или сделать что-то сумасшедшее, как это... это фундаментальная основа для шаблона производителя/потребителя.
Моя версия блокирующей очереди:
public class BlockingQueue<T> where T : class
{
private bool closing;
private readonly Queue<T> queue = new Queue<T>();
public int Count
{
get
{
lock (queue)
{
return queue.Count;
}
}
}
public BlockingQueue()
{
lock (queue)
{
closing = false;
Monitor.PulseAll(queue);
}
}
public bool Enqueue(T item)
{
lock (queue)
{
if (closing || null == item)
{
return false;
}
queue.Enqueue(item);
if (queue.Count == 1)
{
// wake up any blocked dequeue
Monitor.PulseAll(queue);
}
return true;
}
}
public void Close()
{
lock (queue)
{
if (!closing)
{
closing = true;
queue.Clear();
Monitor.PulseAll(queue);
}
}
}
public bool TryDequeue(out T value, int timeout = Timeout.Infinite)
{
lock (queue)
{
while (queue.Count == 0)
{
if (closing || (timeout < Timeout.Infinite) || !Monitor.Wait(queue, timeout))
{
value = default(T);
return false;
}
}
value = queue.Dequeue();
return true;
}
}
public void Clear()
{
lock (queue)
{
queue.Clear();
Monitor.Pulse(queue);
}
}
}
Большое спасибо Марк Гравелл за этот!