7

Mam następujący kod z jednym wątkiem producenta i wieloma wątkami konsumenckimi. Czy wiesz, że wielu klientów jest bezpiecznych dla wątków. Na przykład czy istnieje jakakolwiek szansa, że ​​wątek 1 jest zużyty i podczas gdy wątek 2 zużywa się równolegle i zmienia wartość elementu używanego w wątku 1?BlockingCollection multiple consumer

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; } 
} 
} 

góry dzięki tylko

Odpowiedz

1

Po zużyciu elementu jest on usuwany z kolekcji, więc żaden inny wątek nie będzie mógł uzyskać do niego dostępu (przynajmniej przez kolekcję).

Pamięć podręczna wygląda bardziej jak bufor. Co i tak dodaje na górze kolekcji blokującej? To dziwne, że pamięć podręczna byłaby w stanie konsumować własne elementy.

+0

Dzięki. Masz rację. To jest bufor. Nazwy są nieistotne. Scenariusz, o który chciałem zapytać, to czy istnieje jakakolwiek szansa, że ​​gdy wątek 1 będzie zużywał się i podczas wykonywania tego wątku 2 będzie zużywać równolegle i zmieniać wartość elementu używanego w wątku 1, ponieważ jak widzisz, trzykrotnie dzwoni do konsumenta w Równolegle (Zdarzenie Button1_Click) – pantonis

+0

Następnie odpowiedź brzmi nie, nie ma szans, ale dlatego, że różne wątki nie mogą spożywać tych samych elementów. Czy potrzebujesz różnych wątków, aby uzyskać dostęp do wszystkich elementów w kolekcji? W takim przypadku nie można użyć metody GetConsumingEnumerable(). – fsimonazzi

+0

Nie. Chcę mieć wielu klientów, którzy zużyją bufor tak szybko, jak to możliwe. Więc jakakolwiek manipulacja wykonana w pętli foreach w wątku 1 na obiekcie "przedmiot" nie zostanie zmodyfikowana przez wątek 2? Ponieważ jak widzisz, metoda Konsumpcja jest statyczna. – pantonis

0

BlockingCollection blokuje sam zbiór. Nie obiekty na liście.