Ho il seguente codice con un thread di produzione e più thread di consumo. Sai se più consumatori sono thread-safe. Per esempio c'è qualche possibilità che il thread 1 stia consumando e mentre il thread 2 lo consuma in parallelo e cambia il valore dell'elemento che viene usato nel thread 1?BlockingCollection consumer multiplo
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; }
}
}
Grazie in anticipo solo
Grazie. Hai ragione. È un buffer. I nomi sono irrilevanti. Lo scenario che volevo chiedere è se c'è qualche possibilità che quando il thread 1 sta consumando e mentre si fa quel thread 2 consumi in parallelo e cambi il valore dell'elemento che viene utilizzato nel thread 1 perché come puoi vedere chiamo Consumer tre volte in in parallelo (evento Button1_Click) – pantonis
Quindi la risposta è no, non c'è possibilità, ma perché thread diversi non possono consumare gli stessi elementi. Avete bisogno dei diversi thread per accedere a tutti gli elementi della collezione? In questo caso non è possibile utilizzare il metodo GetConsumingEnumerable(). – fsimonazzi
No. Quello che voglio è avere più consumatori che consumeranno il Buffer al più presto. Quindi qualsiasi manipolazione fatta nel ciclo foreach su Thread 1 sull'oggetto 'item' non verrà modificata dalla Thread 2? Perché come puoi vedere il metodo Consume è statico. – pantonis