Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 阻止收集多个消费者_C#_Multithreading_Thread Safety_Consumer_Blockingcollection - Fatal编程技术网

C# 阻止收集多个消费者

C# 阻止收集多个消费者,c#,multithreading,thread-safety,consumer,blockingcollection,C#,Multithreading,Thread Safety,Consumer,Blockingcollection,我有以下代码,其中包含一个生产者线程和多个消费者线程。您知道多个使用者是否是线程安全的吗。例如,线程1是否有可能正在消费,而线程2是否并行消费并更改线程1中使用的项目的值 namespace BlockingColl { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object se

我有以下代码,其中包含一个生产者线程和多个消费者线程。您知道多个使用者是否是线程安全的吗。例如,线程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; }
}
}
namespace BlockingColl
{
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
尝试
{
对于(int i=0;i<3;i++)
{
ThreadPool.QueueUserWorkItem((x)=>
{
foreach(bc.GetConsumingEnumerable()中的变量项)
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId+“-”+item+“-”+DateTime.Now.ToString(“MM/dd/yyyy hh:MM:ss.fff tt”);
}
});
}
}
捕获(例外)
{
投掷;
}
}
私有无效按钮2\u单击(对象发送者,事件参数e)
{
对于(int i=0;i<3;i++)
{
ThreadPool.QueueUserWorkItem((x)=>
{
Cache.Consume();
});
}
对于(int i=0;i<50000;i++)
{
Cache.bc.TryAdd(新客户端(){ClientId=i,ClientName=“Name”+i});
}
}
}
静态类缓存
{
public static BlockingCollection bc=new BlockingCollection();
公共静态void消费()
{
foreach(bc.GetConsumingEnumerable()中的变量项)
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId+“-”+item+“-”+DateTime.Now.ToString(“MM/dd/yyyy hh:MM:ss.fff tt”);
}
}
}
公共类客户端
{
public int ClientId{get;set;}
公共字符串ClientName{get;set;}
}
}

提前感谢

阻止收藏仅阻止收藏本身。不是列表中的对象。

一旦您使用了元素,它将从集合中删除,因此其他线程将无法访问它(至少通过集合)


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

谢谢。你是对的。它是一个缓冲区。这些名字无关紧要。我想问的场景是,当线程1正在消费时,线程2是否有可能并行消费并更改线程1中使用的项目的值,因为正如您所看到的,我并行调用了消费者三次(Button1_Click事件),然后回答是否,没有机会,但是因为不同的线程不能使用相同的元素。您是否需要不同的线程来访问集合中的所有元素?如果是这种情况,则不能使用GetConsumingEnumerable()方法。否。我想让多个消费者尽快使用缓冲区。因此,线程2不会修改在线程1上的foreach循环中对“item”对象执行的任何操作?因为正如您所看到的,Consume方法是静态的。它不会被修改,因为如果consuming enumerable已经为线程2返回了它,它将不会为线程1返回它。每个线程都会得到一些项目,但不会有重叠。看来你是对的。每个线程都在访问自己的项“实例”