7

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

risposta

1

Una volta consumato un elemento viene rimosso dalla raccolta, quindi nessun altro thread sarà in grado di accedervi (almeno attraverso la raccolta).

Quella cache sembra più un buffer per me. Cosa aggiunge in aggiunta alla collezione di blocchi? È strano che la cache sia in grado di consumare i propri elementi.

+0

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

+0

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

+0

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

0

blocchi A BlockingCollection la raccolta stessa. Non gli oggetti nell'elenco.