Я использую .NET 4.0 BlockingCollection для обработки очереди элементов, каждая из которых должна обрабатываться с помощью операции, которая может занимать до секунды для обработки каждого элемента. Эта очередь элементов может быть добавлена разными потоками.
У меня есть несколько вопросов относительно этого а) разрешить нескольким потребителям работать над этим BlockingCollection? Я заметил GetConsumingEnumerable(), который, по-видимому, применим для отдельных потребительских сценариев. Причина наличия нескольких потребителей заключается в том, что обработка через экземпляр именованного канала может обрабатывать до трех из этих элементов за раз, поэтому я думал, что у меня могут быть три потребителя.
b) Есть ли способ проверить, находится ли элемент в этой очереди, и если да, то вызывающий, который проверяет, есть ли элемент для блокировки до тех пор, пока элемент не будет обработан?
EDIT:
Основываясь на Jon Skeet, ответьте здесь на несколько примеров кода, чтобы проиллюстрировать несколько потребителей, действующих на BlockingCollection, заполненных одним производителем, причем потребители используют GetConsumingEnumerable()
:
static BlockingCollection<string> coll = new BlockingCollection<string>();
static void Consume()
{
foreach (var i in coll.GetConsumingEnumerable())
{
Console.WriteLine(String.Format("Thread {0} Consuming: {1}", Thread.CurrentThread.ManagedThreadId, i));
Thread.Sleep(1000);
}
}
static void Main(string[] args)
{
int item = 0;
Task.Factory.StartNew(() =>
{
while (true)
{
coll.Add(string.Format("Item {0}", item++));
Thread.Sleep(500);
}
});
for (int i = 0; i < 2; i++)
{
Task.Factory.StartNew(() => Consume());
}
while (true) ;
}
Элементы обрабатываются чередующимся образом между двумя потребителями, работающими на двух разных потоках, например.
Thread 4 Consuming: Item 0
Thread 5 Consuming: Item 1
Thread 4 Consuming: Item 2
Thread 5 Consuming: Item 3
Thread 4 Consuming: Item 4