У меня был следующий код в моем приложении в течение нескольких лет, и я никогда не видел проблем с ним.
while ((PendingOrders.Count > 0) || (WaitHandle.WaitAny(CommandEventArr) != 1))
{
lock (PendingOrders)
{
if (PendingOrders.Count > 0)
{
fbo = PendingOrders.Dequeue();
}
else
{
fbo = null;
}
}
// Do Some Work if fbo is != null
}
Где CommandEventArr состоит из NewOrderEvent (событие с автоматическим сбросом) и ExitEvent (событие с ручным сбросом).
Но я не уверен, является ли это потокобезопасным (при условии, что N потоков производителей, которые все блокируют очередь перед постановкой в очередь, и один поток-потребитель, который запускает приведенный выше код). Кроме того, мы можем предположить, что свойство Queue.Count просто возвращает одно значение экземпляра Int32 из класса Queue (без volatile, блокировки, блокировки и т. д.).
Каков обычный шаблон, используемый с Queue и AutoResetEvent, чтобы исправить это и сделать то, что я пытаюсь сделать с кодом выше?
(Отредактировано, чтобы немного изменить вопрос после того, как было правильно указано, что Queue.Count может делать что угодно и зависит от его реализации).