7

我有以下代码,其中包含一个生产者线程和多个消费者线程。你知道多个消费者是否是线程安全的。例如,线程 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; }
}
}

提前致谢

4

2 回答 2

1

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

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

于 2012-11-02T14:11:46.243 回答
0

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

于 2012-11-02T13:41:14.037 回答