Ich habe den folgenden Code mit einem Produzenten-Thread und mehreren Consumer-Threads. Weißt du, ob mehrere Verbraucher threadsicher sind? Zum Beispiel gibt es eine Chance, dass Thread 1 verbraucht und während dieser Thread 2 parallel verbrauchen und den Wert des Elements, das in Thread 1 verwendet wird, ändern?BlockingCollection mehrere Verbraucher
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; }
}
}
Vielen Dank im Voraus
Danke. Du hast recht. Es ist ein Puffer. Die Namen sind irrelevant. Das Szenario, das ich fragen wollte, ist, ob es eine Chance gibt, dass Thread 1 verbraucht und dabei Thread 2 parallel verbraucht und den Wert des Elements ändert, das in Thread 1 verwendet wird, denn wie Sie sehen können, rufe ich Consumer dreimal an in parallel (Button1_Click-Ereignis) – pantonis
Dann ist die Antwort nein, es gibt keine Chance, aber weil verschiedene Threads die gleichen Elemente nicht verbrauchen können. Brauchen Sie die verschiedenen Threads, um auf alle Elemente in der Sammlung zuzugreifen? Wenn das der Fall ist, können Sie die GetConsumingEnumerable() -Methode nicht verwenden. – fsimonazzi
Nein. Ich möchte mehrere Verbraucher haben, die den Puffer so schnell wie möglich verbrauchen. Also wird jede Manipulation, die in der foreach-Schleife auf Thread 1 des 'item'-Objekts vorgenommen wird, nicht durch Thread 2 verändert? Denn wie Sie sehen können, ist die Consume-Methode statisch. – pantonis