Я использую .NET 4.0 BlockingCollection для обработки очереди элементов, каждый из которых должен обрабатываться операцией, которая может занять до секунды для обработки каждого элемента.Эта очередь элементов может быть добавлена различными потоками.
У меня есть пара вопросов относительно этого: а) разрешить нескольким потребителям работать с этой коллекцией BlockingCollection?Я заметил GetConsumingEnumerable (), который, кажется, применим для сценариев с одним потребителем.Причиной наличия нескольких потребителей является то, что обработка через именованный экземпляр канала может обрабатывать до трех из этих элементов одновременно, поэтому я подумал, что у меня может быть три потребителя.
b) Есть ли способпроверки, находится ли элемент в этой очереди, и, если да, получение вызывающей стороны, которая проверяет, есть ли элемент для блокировки, пока элемент не был обработан?
РЕДАКТИРОВАТЬ:
На основе ответа Джона Скита приведен пример кода для иллюстрации нескольких потребителей, действующих на 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