Best Practices in der Verwendung eines lock
Angenommen ich habe die folgende Eigenschaft in einer Klasse, und hat den Zweck verwendet werden, wie eine Sperre.
protected object SyncRoot { get; private set; }
Sowieso, unabhängig davon, ob und wie diese festgelegt wurde. Was ist die beste Praxis zu gehen über die Verwendung von es, wenn es, in der Tat, gesetzt?
Da lock funktioniert nicht mit null-Objekten, sollte ich damit umgehen, wie diese?
lock (SyncRoot ?? new object())
SomeMethod();
Oder sollte ich auf null prüfen, wie diese?
if (SyncRoot != null)
lock (SyncRoot)
SomeMethod();
else
SomeMethod();
Wenn es ist, in der Tat, gesetzt, ich möchte es verwenden, um zu sperren. Ansonsten ich don ' T care. Ist die erste Lösung ineffizient oder überflüssig sowieso?
EDIT: Alle diese Antworten sind gut. Jedoch kann ich nur eine auswählen. Angesichts meiner situation, wie besprochen, mit Luke, gibt es keinen Grund, warum meine SyncRoot, sollte null sein. Der Aufwand für eine Sperre in einem einzigen Multithread-Umgebung ist es kein biggy, aber notwendig, wenn in einem multi-fädelte ein.
(Abstimmung ups für alle 4 ya) Danke Euch allen für Eure schnelle Antworten.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Verwende ich normalerweise eine private member-variable, nicht eine Eigenschaft, dh
Diese Weise seinen immer initialisiert.
Können Sie auch eine nicht statische Variante wie
new object()
- warum würden Sie sich jemals die Mühe zu verlassen, es ist null? (warum würden Sie nicht nur initialisieren, wenn es erklärt, die Beseitigung dieses Anliegen standardmäßig?)Synchronisieren auf
macht keinen Sinn, denn wenn
SyncRoot
istnull
jeder thread ein neues Objekt jedes mal. Synchronisierung über separate Objekte hat keinen Effekt: die threads werden auch weiterhin richtige Weg, denn niemand sonst könnte eventuell die Synchronisierung auf dem gleichennew
Objekt.Sollten Sie initialisieren
SyncRoot
im Konstruktor, bevor der erste thread versucht, erhalten eine Sperre.new object()
ist strittig, da es ein völlig nutzlos idiom.Wird das erste problem sein, denn es wird zu nichts gutem führen Synchronisation:
Der Grund dafür ist, dass, wenn Sie erstellen ein neues Objekt wird auf dem heap, aber es wird kein Hinweis darauf. Also, wenn ein anderer thread kommt, wird es nicht finden... Es wird absolut nutzlos, und es wird nicht blockiert den Zugriff auf den kritischen Abschnitt.
Den zweiten Ansatz funktionieren wird, aber ich kann wirklich nicht verstehen, warum Sie möchten, verwenden Sie die Sperre, wenn es nur verfügbar ist.
Ihre beste option ist immer initialisieren des lock-Objekt, vor jeder Verbraucher das lock-Objekt hat eine chance, es zu benutzen. Die Kosten immer reservieren, das lock-Objekt ist klein, und die Kosten der Einnahme der lock ist klein, wenn es kein Streit-thread.
So hinzufügen lock/no lock prüft alle über Ihren code verdoppelt die Komplexität des Codes und wahrscheinlich vorstellen subtile threading bugs, aber wird wahrscheinlich nicht produziert keine spürbaren performance-Vorteil.
Code vereinfachen: nehmen Sie immer die Sperre.
Aus der Dokumentation:
https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx
Beispiel: