2010-10-24 19 views
18

Ich habe eine Multithread-Anwendung, die mit einer statischen Methode in eine XML-Einstellungsdatei schreibt. Ich möchte verhindern, dass die Datei zweimal zur gleichen Zeit aktualisiert wird (verursacht Zugriff/Schreib-Ausnahme).Lock() in einer statischen Methode

Wie mache ich das?

arbeitet Dies gilt nicht:

namespace Program 
{ 
    public class Settings 
    { 
     private static void SetSettingsValue (string settings, string value) 
     { 
      // make this thread safe to avoid writing to a locked settings xml file 
      lock (typeof(Settings)) 
      { 
       //write data to xml file 
      } 
     } 
    } 
} 
+1

Verfügen Sie über Ihre XML-Datei korrekt (d. H. Über 'using')? Kannst du mehr Code teilen? Auch bei statischen Methoden sollten Sie sich auf private statische Objekte, nicht auf einen Typ, festlegen. Siehe http://msdn.microsoft.com/en-us/library/c5kekcz.aspx –

Antwort

33

Das Konzept von lock() besteht darin, ein vorhandenes Objekt zu verwenden, auf das es verweisen und verwenden kann, um zu steuern, ob der Zugriff gewährt wird.

static object SpinLock = new object(); 

lock(SpinLock) 
{ 
    //Statements 
} 

Wenn die Ausführung verlässt die Sperre() blockieren die Referenz freigegeben wird und alle anderen Threads warten, um den Codeblock ausführen kann (einer nach dem anderen, natürlich) fortzufahren.

+2

Beachten Sie, dass Sie die SpinLock-Referenz in der lock() -Anweisung selbst nicht ändern können. Das Objekt, das zum Sperren verwendet wird, muss für alle Threads zugänglich sein, die den Code ausführen müssen, und es kann die Referenz nicht jedes Mal ändern oder die Threads blockieren sich gegenseitig nicht und Sie erhalten Ressourcenkonflikte/Konflikte. –

37

Sie sollten ein separates, statisches Sperrobjekt erstellen und verwenden. BENUTZEN SIE NICHT EINEN STRING! Zeichenfolgen werden automatisch interniert und es gibt nur eine Instanz jeder programmatisch deklarierten Zeichenfolge, sodass Sie keinen exklusiven Zugriff auf die Sperre garantieren können.

Sie sollten dies tun:

public class A { 
    private static Object LOCK = new Object(); 

    private static void foo() { 
     lock(LOCK) { 
      // Do whatever 
     } 
    } 
} 

(Die Syntax ist möglicherweise falsch, ich bin eine Java Person meist aber die gleichen Regeln zu Sperren und String in C# interning gilt)

Das Schloss Schlüsselwort Erzwingt eine gegenseitige Ausschlusssperre: Nur ein Thread kann ein bestimmtes Objekt gleichzeitig sperren. Wenn ein zweiter Thread foo aufruft, wird er blockiert, bis der erste Thread den Sperrblock verlassen hat.

Nachrichten nach Hause nehmen: Bei einer statischen Methodensperre für eine private statische Variable. Sperren Sie nicht Strings oder typeof (...), da Sie nicht garantieren können, dass niemand anderes dieses Objekt verwendet. Sperren Sie immer ein Objekt, von dem Sie wissen, dass es nicht von jemand anderem berührt wird, indem Sie es privat machen und es neu machen.

+3

Dies ist die beste Antwort in der gesamten Diskussion. Weil Cameron klug genug war, anzugeben, dass das Schloss für die Klasse privat ist. –

+0

Es sollte auch sein, was auch immer das C# -Aquivalent von 'final' ist, aber ich bin kein C# -Typ, also bin ich mir nicht sicher, was das ist. Wenn C# C++ - Stil 'const' hat, dann denke ich, dass ich von Java wechseln werde :) –

+0

Raten Sie nicht: http://stackoverflow.com/questions/55984/what-is-the-difference-between-const-and- readonly –

Verwandte Themen