10

Ich schreibe derzeit eine C# -Anwendung. Ich bin neu in der Verwendung eines ConcurrentDictionary, also haben einige Fragen rund um die Thread-Sicherheit. Erstens, das ist mein Wörterbuch:einige Fragen rund um die Verwendung von ConcurrentDictionary

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

ich instanziiert dies in meiner Klasse und verwenden es alle meine Objekte zu verfolgen, die ITask implementieren. Ich möchte sicherstellen, dass mein Setup in einer Umgebung mit mehreren Threads ordnungsgemäß funktioniert.

Wenn mehrere Threads die Anzahl der Elemente im ConcurrentDictionary abrufen möchten, muss ich sie dann sperren?

Wenn ich einen bestimmten Schlüssel aus dem Wörterbuch erhalten möchte, holen Sie das Objekt dieses Schlüssels und rufen Sie eine Methode auf, muss ich es sperren? Beispiel:

Mehrere Threads könnten die Run-Methode aufrufen, um die Execute-Methode von ITask aufzurufen. Mein Ziel ist es, alles so sicher und so performant wie möglich zu machen.

Antwort

9

Die Verfahren und die Eigenschaften des ConcurrentDictionary sind themself völlig sicher fädeln:

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

Repräsentiert eine Thread-sichere Sammlung von Schlüsselwert-Paaren, die gleichzeitig zugegriffen von mehreren Threads sein kann.

Dies schließt die Count Eigenschaft:

Count zugegriffen snapshot Semantik und stellt die Anzahl der Elemente in der ConcurrentDictionary zur Zeit als Graf war.

jedoch dies tut nicht bedeuten, dass die Gegenstände im Wörterbuch gehalten sind sich sicher fädeln. Das heißt, es gibt nichts, was zwei Threads daran hindert, auf dasselbe Task-Objekt zuzugreifen und zu versuchen, die Execute-Methode darauf auszuführen.Wenn Sie möchten, serialisiert (gesperrt) Zugriff auf jede einzelne Aufgabe für die Execute Methode, dann schlage ich ein Verriegelungsobjekt innerhalb Task und Verriegelungs wenn Execute ausgeführt wird:

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

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

Dies stellt sicher, dass mindestens bei jeder einzelnen Aufgabe doesn Keine laufenden Threads Execute. Ich vermute, das ist es, was Sie aus dem Kontext der Frage und den Namen der Klassen und Methoden suchen.

+0

ist die '.count' Eigenschaft threadsicher? oder die '.Count()' Methode? Was ist der Unterschied? – Zapnologica

2

Alle Methoden von ConcurrentDictionary können aus mehreren Threads aufgerufen werden.

Es garantiert nicht, dass andere Teile Ihres Programms keine Synchronisierung benötigen, da Sie möglicherweise Sperren verwenden müssen, um gleichzeitig auf andere Objekte/mehrere Objekte zuzugreifen.

I.e. Ihr Beispielcode wird für das Abrufen einer Aufgabe und das Ausführen von es gesperrt. Es zeigt ein Beispiel für das Sperren, um atomar auf mehrere Objekte zuzugreifen.

Seitliche Anmerkung: Sie sollten Ihre Sperre für task.Execute() überprüfen, da es anderen Threads verbietet, Task parallel auszuführen. Es kann sein, was Sie erreichen möchten, aber in diesem Fall kann die Verwendung von ConcurrentDictionary übertrieben sein.