多个消费者和查询C#BlockingCollection [英] Multiple consumers and querying a C# BlockingCollection

查看:452
本文介绍了多个消费者和查询C#BlockingCollection的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是.NET 4.0 BlockingCollection来处理每一个需要由操作会占用到第二处理每一个项目进行处理的项目的队列。项的这个队列可以通过不同的线程被加入到

我有几个问题,关于这个 一)允许多个用户在这方面努力BlockingCollection?我注意到GetConsumingEnumerable(),这似乎是适用于单个消费者的场景。这样做的原因有多个消费者的是,处理,通过命名管道实例,最多可处理这三个项目的时间,所以我想我可以有3名消费者。

二)是否有检查是否一个项目在这个队列的一个方式,如果是这样,获得该检查是否有一个项以阻止,直到该项目已被处理呼叫者

编辑:

根据乔恩飞碟双向的答案这里的一些样品code,说明作用于人口由单一生产BlockingCollection多个消费者,与消费者使用

GetConsumingEnumerable()

 静态BlockingCollection<字符串>科尔=新BlockingCollection<字符串>();

静态无效的消费()
{
    的foreach(在coll.GetConsumingEnumerable变种I())
    {
        Console.WriteLine(的String.Format(主题{0}消费:{1},Thread.CurrentThread.ManagedThreadId,I));
        Thread.sleep代码(1000);
    }
}

静态无效的主要(字串[] args)
{
    INT项= 0;

    Task.Factory.StartNew(()=>
    {
        而(真)
        {
            coll.Add(的String.Format(项目{0},项目++));
            Thread.sleep代码(500);
        }
    });

    的for(int i = 0;我2;我++)
    {
        Task.Factory.StartNew(()=>消费());
    }

    而(真);
}
 

的项目是两个消费者对两个不同的线程操作之间进行处理以交错的方式,例如

 发4耗竭与:项目0
主题5消费:项目1
主题4消费:项目2
主题5消耗:项目3
主题4消费:项目4
 

解决方案

多的消费者只需拨打 TryTake 同时 - 每个项目只由一个消费者消费

不过,我相信 GetConsumingEnumerable 将会的还做你想做的。我相信,如果每个调用者调用,每次都会得到一个独立的消费枚举,这再次将确保每个项目只能使用一次。我不知道,当队列为空副手会发生什么 - 我不知道是否的MoveNext()然后块,或返回false

我并没有真正按照你的第二个问题,但...

I am using a .NET 4.0 BlockingCollection to handle a queue of items that each need to be processed by an operation that can take up to a second to process each item. This queue of items can be added to by different threads.

I have a couple of questions regarding this a) allowing multiple consumers to work on this BlockingCollection? I noticed GetConsumingEnumerable(), which seems to be applicable for single consumer scenarios. The reason for having multiple consumers is that the processing, via a named pipe instance, can process up to three of these items at a time, so I thought I could have three consumers.

b) Is there a way of checking to see if an item is on this queue, and if so, getting the caller that checks to see if there is an item to block until the item has been processed?

EDIT:

Based on Jon Skeet's answer here's some sample code to illustrate multiple consumers acting on a BlockingCollection populated by a single producer, with consumers using 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) ;
}

The items are processed in an interleaved manner between the two consumers operating on the two different threads, e.g.

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

解决方案

Multiple consumers can just call Take or TryTake concurrently - each item will only be consumed by a single consumer.

However, I believe GetConsumingEnumerable will also do what you want. I believe if each caller calls that, each will get a separate consuming enumerable, which again will make sure that each item is only consumed once. I'm not sure offhand what happens when the queue becomes empty - I don't know whether MoveNext() then blocks, or returns false.

I didn't really follow your second question though...

这篇关于多个消费者和查询C#BlockingCollection的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆