BlockingCollection多个消费者

时间:2012-11-02 12:42:27

标签: c# multithreading thread-safety consumer blockingcollection

我有一个生产者线程和多个消费者线程的以下代码。你知道多个消费者是否是线程安全的。例如,线程1是否正在消耗并且线程2并行消耗并且更改线程1中使用的项的值?

namespace BlockingColl
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            for (int i = 0; i < 3; i++)
            {

                ThreadPool.QueueUserWorkItem((x) =>
                   {
                       foreach (var item in bc.GetConsumingEnumerable())
                       {
                           Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " - " + item + " - " + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt"));
                       }
                   });
            }
        }
        catch (Exception)
        {

            throw;
        }
    }

    private void button2_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < 3; i++)
        {

            ThreadPool.QueueUserWorkItem((x) =>
               {
                   Cache.Consume();
               });
        }


        for (int i = 0; i < 50000; i++)
        {
            Cache.bc.TryAdd(new Client() { ClientId = i, ClientName = "Name" + i });
        }
    }
}

static class Cache
{
    public static BlockingCollection<Client> bc = new BlockingCollection<Client>();


    public static void Consume()
    {
        foreach (var item in bc.GetConsumingEnumerable())
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " - " + item + " - " + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt"));
        }
    }
}

public class Client
{
    public int ClientId { get; set; }
    public string ClientName { get; set; }
}
}

提前致谢

2 个答案:

答案 0 :(得分:1)

一旦你消耗了一个元素,就会从集合中删除它,所以没有其他线程可以访问它(至少通过集合)。

那个缓存看起来更像是一个缓冲区。无论如何,它在阻塞集合之上添加了什么?高速缓存能够使用自己的元素是很奇怪的。

答案 1 :(得分:0)

BlockingCollection仅阻止集合本身。不是列表中的对象。