2016-04-18 14 views
2

Ich lese hier:Ist es sicher, lock() mit Tasks zu verwenden?

.NET async, can a single thread time-slice between tasks?

, dass, wenn Sie nicht ausdrücklich verwenden async/await, Aufgaben nicht "Zeitscheibe" auf dem gleichen Thread im Backend-Thread-Pool. Ist das garantiert? Oder nur ein Nebeneffekt der aktuellen Implementierung der TPL?

Wenn nicht garantiert, wäre es Problemen mit lock() mit:

Betrachten wir zwei Aufgaben, die ein Verfahren zuzugreifen, die locks auf eine vollständige Transaktion Serialport (eine Nachricht senden und empfangen, oder Timeout) vor der Freigabe. Wenn Time-Slicing im selben Thread auftritt und der SerialPort-Zugriff langsam genug ist, würde die lock ihre Arbeit nicht ausführen (indem sie beide Aufrufe durchlässt, da sie sich technisch im selben Thread befinden).

+0

Da Sie normalerweise nicht um externe Anrufe "sperren", was auch immer Verhalten dort ist, sollte kein Problem für echten Code sein ... –

+1

Ja, es ist garantiert, weil der Task-Scheduler (auch benutzerdefinierte) auf eine bestimmte Task-Ausführung warten wird Rendite oder Rendite. Sie können physisch nicht zwei Codebereiche gleichzeitig im selben Thread ausführen, ohne dass der Task dem Scheduler zugewiesen wird. –

+1

Beachten Sie, dass es sich bei dieser Frage um rohen TPL-Code handelt, da dieser nicht auf 'async' /' await'-Code zutrifft - Sie können '' '' '' '' nicht erwarten, da Sie einen Fehler bekommen im Körper einer Lock-Anweisung "versucht, es zu tun. –

Antwort

1

Ja, solange Sie nichts tun, dass (einige Teile) Code ausführen auf einem anderen Thread macht (await, Task.Run(), Task.ContinueWith(), Thread, ...), dann sicher es ist lock oder eine andere Gewinde- zu verwenden Synchronisationsmechanismus.

Eine mögliche Ausnahme ist, wenn Sie eine benutzerdefinierte TaskScheduler (z TaskScheduler.FromCurrentSynchronizationContext()) haben und Sie irgendwie, dass Scheduler machen versuchen, mehr Task s auszuführen, während die Task noch ausgeführt wird (zum Beispiel so etwas wie Application.DoEvents()). In diesem Fall wird Ihr Task immer noch nicht in einen anderen Thread verschoben, aber er kann pausiert werden, während ein anderer Task auf demselben Thread ausgeführt wird. Aber diese Situation sollte äußerst selten sein.

Verwandte Themen