Wann ist es angemessen, entweder die Monitor
Klasse oder das lock
Schlüsselwort für die Thread-Sicherheit in C # zu verwenden?
EDIT:
Aus den bisherigen Antworten geht hervor, dass dies lock
eine kurze Hand für eine Reihe von Anrufen an die Monitor
Klasse ist. Wofür genau ist der Lock Call Shorthand? Oder expliziter:
class LockVsMonitor
{
private readonly object LockObject = new object();
public void DoThreadSafeSomethingWithLock(Action action)
{
lock (LockObject)
{
action.Invoke();
}
}
public void DoThreadSafeSomethingWithMonitor(Action action)
{
// What goes here ?
}
}
Aktualisieren
Vielen Dank für Ihre Hilfe: Ich habe eine weitere Frage als Folge einiger der von Ihnen bereitgestellten Informationen gestellt. Da Sie sich in diesem Bereich gut auskennen, habe ich den Link gepostet: Was ist falsch an dieser Lösung zum Sperren und Verwalten gesperrter Ausnahmen?
lock
Block gemacht werden.Pulse
einfaches Sperren. Dies ist in einigen fortgeschrittenen Multithreading-Szenarien wichtig. Ich habe noch niePulse
direkt verwendet.lock
ist nur eine Abkürzung fürMonitor.Enter
mittry
+finally
undMonitor.Exit
. Verwenden Sie die lock-Anweisung, wann immer dies ausreicht. Wenn Sie TryEnter benötigen, müssen Sie Monitor verwenden.quelle
Eine lock-Anweisung entspricht:
Beachten Sie jedoch, dass Monitor auch Wait () und Pulse () ausführen kann , die häufig in komplexen Multithreading-Situationen hilfreich sind.
Aktualisieren
In C # 4 ist es jedoch anders implementiert:
Vielen Dank an CodeInChaos für Kommentare und Links
quelle
Monitor
ist flexibler. Mein bevorzugter Anwendungsfall für die Verwendung von Monitor ist, wenn Sie nicht auf Ihren Zug warten und einfach überspringen möchten :quelle
Wie andere gesagt haben,
lock
ist "gleichwertig" mitAber nur aus Neugier
lock
wird der erste Hinweis, den Sie ihm geben , erhalten bleiben und nicht geworfen, wenn Sie ihn ändern. Ich weiß, dass es nicht empfohlen wird, das gesperrte Objekt zu ändern, und Sie möchten es nicht tun.Aber auch für die Wissenschaft funktioniert das gut:
... und das nicht:
Error:
Dies liegt daran
Monitor.Exit(lockObject);
, dass auf etwas reagiert wird,lockObject
das sich geändert hat, weilstrings
es unveränderlich ist. Dann rufen Sie es aus einem nicht synchronisierten Codeblock auf. Aber trotzdem. Dies ist nur eine lustige Tatsache.quelle
object temp = lockObject; Monitor.Enter(temp); <...locked code...> Monitor.Exit(temp);
Beides ist dasselbe. lock ist ein scharfes Schlüsselwort und verwendet die Monitor-Klasse.
http://msdn.microsoft.com/en-us/library/ms173179(v=vs.80).aspx
quelle
Die Sperre und das grundlegende Verhalten des Monitors (Enter + Exit) sind mehr oder weniger gleich, aber der Monitor verfügt über mehr Optionen, die Ihnen mehr Synchronisationsmöglichkeiten ermöglichen.
Das Schloss ist eine Verknüpfung und die Option für die grundlegende Verwendung.
Wenn Sie mehr Kontrolle benötigen, ist der Monitor die bessere Option. Sie können Wait, TryEnter und Pulse für erweiterte Verwendungen (wie Barrieren, Semaphoren usw.) verwenden.
quelle
Zusätzlich zu allen obigen Erklärungen ist lock eine C # -Anweisung, während Monitor eine Klasse von .NET ist, die sich im System.Threading-Namespace befindet.
quelle
Sperren Schlüsselwort Lock stellt sicher, dass ein Thread gleichzeitig einen Code ausführt.
lock (lockObject)
Das Schlüsselwort lock markiert einen Anweisungsblock als kritischen Abschnitt, indem die Sperre für den gegenseitigen Ausschluss für ein bestimmtes Objekt abgerufen, eine Anweisung ausgeführt und dann die Sperre aufgehoben wird
Wenn ein anderer Thread versucht, einen gesperrten Code einzugeben, wartet er blockiert, bis das Objekt freigegeben wird.
Monitor Der Monitor ist eine statische Klasse und gehört zum System.Threading-Namespace.
Es bietet eine exklusive Sperre für das Objekt, sodass zu einem bestimmten Zeitpunkt nur ein Thread in den kritischen Abschnitt eintreten kann.
Unterschied zwischen Monitor und Sperre in C #
Die Sperre ist die Verknüpfung für Monitor. Geben Sie try und finally ein. Sperrgriffe versuchen und blockieren schließlich intern Lock = Monitor + versuchen es schließlich.
Wenn Sie mehr Kontrolle mit erweiterten Multithreading - Lösungen zu implementieren
TryEnter()
Wait()
,Pulse()
undPulseAll()
Methoden, dann ist die Monitor - Klasse Ihre Wahl.C #
Monitor.wait()
: Ein Thread wartet darauf, dass andere Threads benachrichtigt werden.Monitor.pulse()
: Ein Thread benachrichtigt einen anderen Thread.Monitor.pulseAll()
: Ein Thread benachrichtigt alle anderen Threads innerhalb eines Prozessesquelle