Angenommen, ich habe in einer Klasse die folgende Eigenschaft, und ihr Zweck besteht darin, als Sperre verwendet zu werden.
%Vor%Egal, wie und ob dies eingestellt wurde. Was ist die beste Vorgehensweise, um es zu benutzen, wenn es tatsächlich eingestellt ist?
Da die Sperre nicht mit Null-Objekten funktioniert, sollte ich das so behandeln?
%Vor%Oder sollte ich auf Null so prüfen?
%Vor%Wenn es tatsächlich festgelegt ist, möchte ich es zum Sperren verwenden. Ansonsten ist es mir egal. Ist die erste Lösung ineffizient oder überflüssig?
EDIT: All diese Antworten sind gut. Ich kann jedoch nur eins auswählen. Angesichts meiner mit Luke besprochenen Situation gibt es keinen Grund, warum mein SyncRoot null sein sollte. Der Overhead einer Sperre in einer Umgebung mit einem einzelnen Thread ist nicht groß, aber in einem Multithread-Fall notwendig.
(Danke für alle 4 von ya) Vielen Dank für Ihre schnellen Antworten.
Normalerweise verwende ich eine private Member-Variable und keine Eigenschaft, zB
%Vor%Auf diese Weise wird es immer initialisiert.
Sie können auch eine nicht statische Version wie
verwenden %Vor%Synchronisieren auf
%Vor% macht keinen Sinn, denn wenn SyncRoot
null
ist, erhält jeder Thread jedes Mal ein neues Objekt. Das Synchronisieren auf separaten Objekten hat keine Auswirkungen: Threads werden sofort fortgesetzt, da niemand sonst möglicherweise auf demselben new
-Objekt synchronisieren kann.
Sie sollten SyncRoot
im Konstruktor initialisieren, bevor der erste Thread versucht, eine Sperre zu erhalten.
Am besten ist es, das Sperrobjekt immer zu initialisieren, bevor ein Benutzer des Sperrobjekts es nutzen kann. Die Kosten, um das Sperrobjekt immer zuzuweisen, sind gering und die Kosten für die Sperrung sind gering, wenn kein Threadkonflikt vorliegt.
Das Hinzufügen von Lock / No-Lock-Checks über Ihren gesamten Code wird die Komplexität Ihres Codes verdoppeln und wahrscheinlich zu kleinen Threading-Bugs führen, aber wahrscheinlich keinen spürbaren Performance-Vorteil bringen.
Vereinfachen Sie Ihren Code: Nehmen Sie immer das Schloss.
Angenommen, ich habe in einer Klasse die folgende Eigenschaft, und ihr Zweck besteht darin, als Sperre verwendet zu werden.
%Vor%Egal, wie und ob dies eingestellt wurde. Was ist die beste Vorgehensweise, um es zu benutzen, wenn es tatsächlich eingestellt ist?
Da die Sperre nicht mit Null-Objekten funktioniert, sollte ich das so behandeln?
%Vor%Oder sollte ich auf Null so prüfen?
%Vor%Wenn es tatsächlich festgelegt ist, möchte ich es zum Sperren verwenden. Ansonsten ist es mir egal. Ist die erste Lösung ineffizient oder überflüssig?
EDIT: All diese Antworten sind gut. Ich kann jedoch nur eins auswählen. Angesichts meiner mit Luke besprochenen Situation gibt es keinen Grund, warum mein SyncRoot null sein sollte. Der Overhead einer Sperre in einer Umgebung mit einem einzelnen Thread ist nicht groß, aber in einem Multithread-Fall notwendig.
(Danke für alle 4 von ya) Vielen Dank für Ihre schnellen Antworten.
Aus der Dokumentation: Ссылка
Vermeiden Sie im Allgemeinen das Sperren für einen öffentlichen Typ oder Instanzen, die nicht von Ihrem Code gesteuert werden. Die allgemeinen Konstrukte lock (this), lock (typeof (MyType)) und lock ("myLock") verletzen diese Richtlinie:
- lock (this) ist ein Problem, wenn auf die Instanz öffentlich zugegriffen werden kann.
- lock (typeof (MyType)) ist ein Problem, wenn MyType öffentlich zugänglich ist.
- lock ("myLock") ist ein Problem, da jeder andere Code, der denselben String verwendet, denselben Zugriff hat.
Bewährte Methode besteht darin, ein privates Objekt zum Sperren auf oder ein privates Objekt zu definieren statische Objektvariable , um Daten zu schützen, die allen Instanzen gemeinsam sind.
Beispiel:
%Vor%Normalerweise verwende ich eine private Member-Variable und keine Eigenschaft, zB
%Vor%Auf diese Weise wird es immer initialisiert.
Sie können auch eine nicht statische Version wie
verwenden %Vor%Synchronisieren auf
%Vor%macht keinen Sinn, denn wenn %code% %code% ist, erhält jeder Thread jedes Mal ein neues Objekt. Das Synchronisieren auf separaten Objekten hat keine Auswirkungen: Threads werden sofort fortgesetzt, da niemand sonst möglicherweise auf demselben %code% -Objekt synchronisieren kann.
Sie sollten %code% im Konstruktor initialisieren, bevor der erste Thread versucht, eine Sperre zu erhalten.
Am besten ist es, das Sperrobjekt immer zu initialisieren, bevor ein Benutzer des Sperrobjekts es nutzen kann. Die Kosten, um das Sperrobjekt immer zuzuweisen, sind gering und die Kosten für die Sperrung sind gering, wenn kein Threadkonflikt vorliegt.
Das Hinzufügen von Lock / No-Lock-Checks über Ihren gesamten Code wird die Komplexität Ihres Codes verdoppeln und wahrscheinlich zu kleinen Threading-Bugs führen, aber wahrscheinlich keinen spürbaren Performance-Vorteil bringen.
Vereinfachen Sie Ihren Code: Nehmen Sie immer das Schloss.
Aus der Dokumentation: Ссылка
Vermeiden Sie im Allgemeinen das Sperren für einen öffentlichen Typ oder Instanzen, die nicht von Ihrem Code gesteuert werden. Die allgemeinen Konstrukte lock (this), lock (typeof (MyType)) und lock ("myLock") verletzen diese Richtlinie:
- lock (this) ist ein Problem, wenn auf die Instanz öffentlich zugegriffen werden kann.
- lock (typeof (MyType)) ist ein Problem, wenn MyType öffentlich zugänglich ist.
- lock ("myLock") ist ein Problem, da jeder andere Code, der denselben String verwendet, denselben Zugriff hat.
Bewährte Methode besteht darin, ein privates Objekt zum Sperren auf oder ein privates Objekt zu definieren statische Objektvariable , um Daten zu schützen, die allen Instanzen gemeinsam sind.
Beispiel:
%Vor%