10

Obecnie piszę aplikację C#. Jestem nowy w użyciu ConcurrentDictionary, więc miej kilka pytań dotyczących bezpieczeństwa wątków. Po pierwsze, jest to mój słownik:kilka pytań dotyczących używania ConcurrentDictionary

/// <summary> 
    /// A dictionary of all the tasks scheduled 
    /// </summary> 
    private ConcurrentDictionary<string, ITask> tasks; 

I instancji w moim klasy i użyć go do śledzenia wszystkich moich obiektów, które implementują iTask. Chcę, aby moja konfiguracja działała poprawnie w środowisku wielowątkowym.

Jeśli wiele wątków chce uzyskać liczbę elementów w ConcurrentDictionary, czy muszę je zablokować?

Jeśli chcę uzyskać określony klucz ze słownika, pobrać obiekt tego klucza i wywołać metodę na nim, czy muszę go zablokować? np .:

/// <summary> 
    /// Runs a specific task. 
    /// </summary> 
    /// <param name="name">Task name.</param> 
    public void Run(string name) 
    { 
     lock (this.syncObject) 
     { 
      var task = this.tasks[name] as ITask; 
      if (task != null) 
      { 
       task.Execute(); 
      } 
     } 
    } 

Utrzymywanie umysłu w wielu wątkach może wywoływać metodę Run w celu wywołania metody Execute programu ITask. Moim celem jest, aby wszystko było bezpieczne i jak najbardziej wydajne.

Odpowiedz

9

Sposoby i właściwości ConcurrentDictionary samym sobą całkowicie nić bezpieczne:

http://msdn.microsoft.com/en-us/library/dd287191.aspx

reprezentuje nić bezpieczny zbiór par klucz wartość, którą można uzyskać przez wielu wątków jednocześnie.

ta obejmuje właściwość Count:

Hrabia ma semantykę migawki i reprezentuje liczbę elementów w ConcurrentDictionary w tej chwili kiedy hrabia był dostępne.

Jednak to robi nie oznacza, że ​​obiekty utrzymywane wewnątrz słownika są sami wątku bezpieczne. Oznacza to, że nic nie powstrzymuje dwóch wątków przed dostępem do tego samego obiektu Task i próbuje uruchomić na nim metodę Execute.Jeśli chcieliby odcinkach (zablokowane) dostęp do każdego zadania dla metody Execute, to proponuję mając obiekt blokujący wewnątrz Task i blokowania podczas uruchamiania Execute:

public class Task 
{ 
    private object _locker = new object(); 

    public void Execute() 
    { 
     lock (_locker) { 
      // code here 
     } 
    } 
} 

Gwarantuje to, że co najmniej raz na indywidualne zadanie robi nie ma wielu wątków o numerze Execute. Zgaduję, że właśnie o to pytasz z kontekstu pytania i nazw klas i metod.

+0

jest zabezpieczeniem wątku '.count'? lub metoda '.Count()'? Jaka jest różnica? – Zapnologica

2

Wszystkie metody ConcurrentDictionary można bezpiecznie wywoływać z wielu wątków.

Nie gwarantuje, że inne części programu nie wymagają synchronizacji, ponieważ może być konieczne użycie blokad, aby uzyskać dostęp do innych obiektów/wielu obiektów w tym samym czasie.

tj. Twój przykładowy kod blokuje się zarówno w celu pobrania zadania, jak i jego wykonania. Pokazuje przykład blokowania dostępu do wielu obiektów atomowo.

Uwaga boczna: należy sprawdzić blokadę pod kątem task.Execute(), ponieważ zabrania ona innym wątkom wykonywania zadania równolegle. Być może to, co chcesz osiągnąć, ale w tym przypadku użycie ConcurrentDictionary może być przesadzone.

Powiązane problemy