2013-08-16 2 views
8

Unter den folgenden Code zuzuweisen, was in einer Multithread-Umgebung geschieht:ist es sicher, fädeln, einen neuen Wert zu einem statischen Objekt in C#

static Dictionary<string,string> _events = new Dictionary<string,string>(); 

public static Dictionary<string,string> Events { get { return _events;} } 

public static void ResetDictionary() 
{ 
    _events = new Dictionary<string,string>(); 
} 

in einer Multithread-Umgebung dieses Verfahren und diese Eigenschaft kann in die zugegriffen werden gleichzeitig durch verschiedene Threads.

Ist es threadsicher, ein neues Objekt einer statischen Variable zuzuweisen, auf die in verschiedenen Threads zugegriffen werden kann? Was kann schiefgehen?

Gibt es einen Zeitpunkt, zu dem Ereignisse null sein können? Wenn 2 Threads gleichzeitig anrufen Events und ResetDictionary().

+1

Wenn zwei Threads 'Events' und' ResetDictionary' gleichzeitig aufrufen, dann könnte folgendes passieren: Thread 1 macht etwas mit 'Events' und' Events' enden mit einem leeren Wörterbuch, * * oder ** Thread 2 ruft 'ResetDictionary' zuerst auf und dann wird etwas durch Thread2 getan.' Events' enden nicht mit 'null', es sei denn, sie sind durch einen anderen Thread auf 'null' gesetzt. Dies kann zu einer Nullzeigerausnahme führen, wenn ein Thread "Events! = null" überprüft, bevor "ResetDictionary" von einem anderen aufgerufen wird. – Nolonar

+2

Verwenden Sie eine statische Variable, bei der Sie erwarten, dass sich der Variablenwert nicht ändert (ähnlich wie bei jeder Anfrage) oder auch wenn sich die Änderung nicht auf Ihre Anwendung auswirkt (dies hat jedoch Auswirkungen). Es gibt Möglichkeiten, dass Ihre Anwendung mit falscher Logik ausgeführt wird Es wird nicht einmal eine Ausnahme gemacht, man bedenke, dass ein Benutzer jeden Wert ändert und dann jede andere eingehende Anfrage falsche Daten verarbeitet, bis der Wert von einer anderen Logik zurückgesetzt wird. Verwenden Sie also statische Variablen mit Bedacht. –

Antwort

13

Ist es threadsicher, ein neues Objekt einer statischen Variable zuzuweisen, auf die in verschiedenen Threads zugegriffen werden kann?

Grundsätzlich ja. In dem Sinne, dass die Eigenschaft niemals ungültig sein wird oder null.

Was kann schief gehen?

Ein Lese-Thread kann weiterhin das alte Wörterbuch verwenden, nachdem ein anderer Thread es zurückgesetzt hat. Wie schlimm das ist, hängt ganz von Ihrer Programmlogik und Ihren Anforderungen ab.

0

Wenn Sie alles in einer Multithreading-Umgebung steuern möchten, müssen Sie ein Flag verwenden, auf das alle Stufen zugreifen können, und die Methoden steuern, die Sie in Ihrem Wörterbuch verwenden!

// the dictionary 
static Dictionary<string, string> _events = new Dictionary<string, string>(); 

// public boolean 
static bool isIdle = true; 

// metod that a thread calls 
bool doSomthingToDictionary() 
{ 
    // if another thread is using this method do nothing, 
    // just return false. (the thread will get false and try another time!) 
    if (!isIdle) return false; 

    // if it is Idle then: 
    isIdle = false; 
    ResetDictionary(); // do anything to your dictionary here 
    isIdle = true; 
    return true; 
} 

eine andere Sache! Sie können die Invoke-Methode verwenden, um sicherzustellen, dass ein Thread eine Variable manipuliert oder eine Funktion in einem anderen Thread aufruft. siehe den Link: Cleanest Way to Invoke Cross-Thread Events