我有以下代码与一个生产者线程和多个消费者线程。你知道多个消费者是否线程安全。例如,是否有线程1消耗的可能性,并且线程2并行使用并更改线程1中使用的项目的值?BlockingCollection多个消费者
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; }
}
}
感谢事先只
谢谢。你是对的。这是一个缓冲区。名字是无关紧要的。我想问的情景是,当线程1消耗并且在线程2并行使用并更改线程1中使用的项目的值时,是否有任何机会,因为您可以看到我称为消费者三次并行(Button1_Click事件) – pantonis
然后答案是否定的,没有机会,但因为不同的线程不能消耗相同的元素。你需要不同的线程来访问集合中的所有元素吗?如果是这种情况,则不能使用GetConsumingEnumerable()方法。 – fsimonazzi
不,我想要的是让多个消费者尽快消费缓冲区。所以在'item'对象的Thread 1的foreach循环中所做的任何操作都不会被Thread 2修改?因为你可以看到Consume方法是静态的。 – pantonis