356 Stimmen

C# Version von Java's synchronized Schlüsselwort?

Verfügt c# über eine eigene Version des Java-Schlüsselworts "synchronized"?

D.h. in Java kann es entweder einer Funktion, einem Objekt oder einem Codeblock zugeordnet werden, etwa so:

public synchronized void doImportantStuff() {
   // dangerous code goes here.
}

ou

public void doImportantStuff() {
   // trivial stuff

   synchronized(someLock) {
      // dangerous code goes here.
   }
}

528voto

Marc Gravell Punkte 970173

Erstens: Die meisten Klassen werden nie thread-sicher sein müssen. Verwenden Sie YAGNI : Wenden Sie Thread-Safety nur an, wenn Sie wissen, dass Sie es tatsächlich benutzen (und testen) werden.

Für das Material auf Methodenebene gibt es [MethodImpl] :

[MethodImpl(MethodImplOptions.Synchronized)]
public void SomeMethod() {/* code */}

Dies kann auch für Accessoren (Eigenschaften und Ereignisse) verwendet werden:

private int i;
public int SomeProperty
{
    [MethodImpl(MethodImplOptions.Synchronized)]
    get { return i; }
    [MethodImpl(MethodImplOptions.Synchronized)]
    set { i = value; }
}

Beachten Sie, dass feldartige Ereignisse sind standardmäßig synchronisiert, während automatisch implementierte Eigenschaften sind nicht :

public int SomeProperty {get;set;} // not synchronized
public event EventHandler SomeEvent; // synchronized

Mir persönlich gefällt die Implementierung von MethodImpl wenn er abschließt this o typeof(Foo) - was gegen die bewährte Praxis verstößt. Die bevorzugte Option ist die Verwendung eigener Schlösser:

private readonly object syncLock = new object();
public void SomeMethod() {
    lock(syncLock) { /* code */ }
}

Beachten Sie, dass bei feldartigen Ereignissen die Implementierung der Sperre vom Compiler abhängt; in älteren Microsoft-Compilern ist es eine lock(this) / lock(Type) - aber, in neueren Compilern verwendet er Interlocked Updates - also thread-safe ohne die unangenehmen Teile.

Dies ermöglicht eine detailliertere Nutzung und die Verwendung von Monitor.Wait / Monitor.Pulse usw. zur Kommunikation zwischen Threads.

Eine verwandte Blogeintrag (später überarbeitet ).

68voto

Jan Gressmann Punkte 5391
static object Lock = new object();

lock (Lock) 
{
// do stuff
}

39voto

Konrad Rudolph Punkte 503837

Verfügt c# über eine eigene Version des Java-Schlüsselworts "synchronized"?

Nein. In C# müssen Sie explizit lock Ressourcen, an denen Sie synchron über asynchrone Threads hinweg arbeiten wollen. lock öffnet einen Block; er funktioniert nicht auf Methodenebene.

Der zugrunde liegende Mechanismus ist jedoch ähnlich, da lock funktioniert durch den Aufruf von Monitor.Enter (und anschließend Monitor.Exit ) auf die Laufzeit. Java arbeitet auf die gleiche Weise, gemäß der Dokumentation zur Sonne .

6voto

ASA Punkte 1811

Beachten Sie, bei vollen Wegen die Linie: [MethodImpl(MethodImplOptions.Synchronized)] sollte wie folgt aussehen

[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]

5voto

James Punkte 2030

Sie können die lock Anweisung an. Ich denke, dies kann nur die zweite Version ersetzen. Denken Sie auch daran, dass beide synchronized y lock auf ein Objekt einwirken müssen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X