Несколько очередей было бы полезно, если вы хотите активно разделять работу - то есть иметь разные потоки / пулы для разных типов событий. Если вы хотите разделить нагрузку, есть еще один вариант - использовать интерфейс (а не базовый класс). С базовым классом все в порядке, но я не могу придумать ничего такого, что предписывало бы базовый класс через интерфейс. Или даже просто делегат на работу, чтобы сделать!
Также - я не уверен, что вам нужно событие сброса в этом случае; Вы часто можете работать с производителем / потребителем только с помощью lock и Monitor.Pulse / Wait (с меньшими накладными расходами, поскольку не задействованы никакие объекты OS - только управляемые объекты). Тем не менее, если код в настоящее время стабилен, возможно, оставьте «как есть» - многопоточность достаточно сложна, чтобы разобраться с ней один раз, не говоря уже о двух ...
Но для справки это было бы что-то вроде:
while(true) {
T item;
lock(lockObj) {
if(queue.Count == 0) { // empty
Monitor.Wait(lockObj);
continue; // ensure there is genuinely something to do
}
item = queue.Dequeue();
}
// TODO: process item
}
...
void Add(T item) {
lock(lockObj) {
queue.Enqueue(item);
if(queue.Count == 1) { // first
Monitor.PulseAll(lockObj);
}
}
}
(и не забывайте PulseAll при очистке очередей)