Ich möchte einige neue Threads für jeweils eine wiederholte Operation starten. Aber wenn eine solche Operation bereits ausgeführt wird, möchte ich die aktuelle Aufgabe verwerfen. In meinem Szenario brauche ich nur sehr aktuelle Daten - gelöschte Daten sind kein Problem.
In der MSDN habe ich die Mutex
-Klasse gefunden, aber wie ich es verstehe, wartet sie auf ihren Zug und blockiert den aktuellen Thread. Auch ich möchte Sie fragen: Gibt es schon etwas im .NET Framework, das das folgende macht:
return
(und lassen Sie mich einen Zähler für Statistiken erhöhen) Die lock(someObject)
-Anweisung, auf die Sie vielleicht gestoßen sind, ist syntaktischer Zucker um Monitor.Enter
und Monitor.Exit
.
Wenn Sie den Monitor jedoch auf diese ausführlichere Weise verwenden, können Sie auch Monitor.TryEnter
verwenden, mit dem Sie überprüfen können, ob Sie die Sperre erhalten können - also prüfen, ob jemand sie bereits hat und ausführt Code.
Also statt dessen:
%Vor%probiere dies (Option 1) :
%Vor%(Sie werden wahrscheinlich versuchen ... endgültig dort hinein, um sicherzustellen, dass die Sperre freigegeben wird)
oder verzichten Sie auf die explizite Sperre und machen Sie dies
(Option 2)
%Vor% [Edit: als Antwort auf Ihre Frage zu this
]
Nein - verwenden Sie nicht this
bis lock
on. Erstellen Sie ein privat definiertes Objekt, das als Ihre Sperre fungiert.
Sonst haben Sie dieses potentielle Problem:
%Vor%Im obigen Beispiel ist es einem externen Code gelungen, die interne Sperrung unserer Klasse zu unterbrechen, indem nur eine Sperre für etwas entfernt wurde, auf das extern zugegriffen werden konnte.
Es ist viel besser, ein privates Objekt zu erstellen, das Sie kontrollieren und auf das niemand außerhalb Ihrer Klasse Zugriff hat, um diese Art von Problemen zu vermeiden. Dies beinhaltet, dass this
oder der Typ selbst typeof(MyClassWithLockInside)
zum Sperren nicht verwendet wird.
Eine Möglichkeit wäre, mit einem Reentrancy-Sentinel zu arbeiten:
Sie könnten ein int
-Feld definieren (mit 0 initialisieren) und es über Interlocked.Increment
Interlocked.Decrement
.
Eine andere Option:
Aus Ihrer Beschreibung geht hervor, dass Sie ein Producer-Consumer-Szenario haben ...
In diesem Fall könnte es hilfreich sein, so etwas wie BlockingCollection
zu verwenden fadensicher und meist sperrfrei ...
Eine andere Option wäre die Verwendung von ConcurrentQueue
oder ConcurrentStack
...
Auf der folgenden Website finden Sie möglicherweise nützliche Informationen (der PDf ist auch herunterladbar - kürzlich heruntergeladen es selbst). Die Kapitel "Suspend and Resume" oder "Aborting" des Threads "Advanced Threading" sind möglicherweise etwas, an dem Sie interessiert sind.
Sie sollten die atomaren Operationen der Interlocked-Klasse verwenden - für die beste Leistung, da Sie keine Sychronisierungen auf Systemebene verwenden werden (jede "Standard" -Verknüpfung benötigt sie und beinhaltet einen Systemaufruf-Overhead). // einfacher nicht-reentranter Mutex ohne Eigentümer, einfach remake um // diese Funktionen zu unterstützen (setze den Besitzer nach dem Erwerb der Sperre (vergleiche Threadreferenz mit Thread.CurrentThread zum Beispiel), und überprüfe auf übereinstimmende Identität, addiere Zähler für Reentrancy) // kann bool nicht verwenden, da es von CompareExchange nicht unterstützt wird private int Sperre;
%Vor%Tags und Links .net c# multithreading