Gibt es gute Regeln für die Verwendung von Task.Delay im Vergleich zu Thread.Sleep ?
- Gibt es einen Mindestwert, um sicherzustellen, dass einer gegenüber dem anderen effektiv / effizient ist?
- Gibt es einen Overhead bei der Verwendung von Task.Delay, da die Kontextumschaltung auf einer asynchronen / wartenden Zustandsmaschine verursacht wird?
Antworten:
Verwenden
Thread.Sleep
Sie diese Option, wenn Sie den aktuellen Thread blockieren möchten.Verwenden
Task.Delay
Sie diese Option, wenn Sie eine logische Verzögerung wünschen, ohne den aktuellen Thread zu blockieren.Effizienz sollte bei diesen Methoden kein vorrangiges Anliegen sein. Sie werden hauptsächlich in der Praxis als Wiederholungszeitgeber für E / A-Vorgänge verwendet, die eher in der Größenordnung von Sekunden als von Millisekunden liegen.
quelle
Thread.Sleep
blockiert den aktuellen Thread, der einen Kontextwechsel verursacht. Wenn Sie einen Thread-Pool verwenden, kann dies auch dazu führen, dass ein neuer Thread zugewiesen wird. Beide Vorgänge sind ziemlich umfangreich, während das vonTask.Delay
etc bereitgestellte kooperative Multitasking den gesamten Overhead vermeiden, den Durchsatz maximieren, die Stornierung ermöglichen und saubereren Code bereitstellen soll.onesi: I would use
Thread.Sleep`, um innerhalb einer synchronen Methode zu warten. Im Produktionscode mache ich das jedoch nie. Nach meiner Erfahrung war alles, wasThread.Sleep
ich jemals gesehen habe, ein Hinweis auf ein Designproblem, das ordnungsgemäß behoben werden muss.Der größte Unterschied zwischen
Task.Delay
undThread.Sleep
besteht darin, dassTask.Delay
asynchron ausgeführt werden soll. Die VerwendungTask.Delay
in synchronem Code ist nicht sinnvoll . Es ist eine sehr schlechte Idee,Thread.Sleep
in asynchronem Code zu verwenden.Normalerweise rufen Sie
Task.Delay()
mit demawait
Schlüsselwort an:oder, wenn Sie vor der Verzögerung Code ausführen möchten:
Ratet mal, was dies drucken wird? Läuft für 0,0070048 Sekunden. Wenn wir stattdessen das
await delay
Obige verschiebenConsole.WriteLine
, wird Running für 5.0020168 Sekunden gedruckt.Schauen wir uns den Unterschied an mit
Thread.Sleep
:Versuchen Sie vorherzusagen, was dies drucken wird ...
Es ist auch interessant festzustellen , dass die
Thread.Sleep
Genauigkeit weitaus genauer ist, die Genauigkeit von ms kein wirkliches Problem darstellt undTask.Delay
minimal 15 bis 30 ms dauern kann. Der Overhead für beide Funktionen ist im Vergleich zu ihrer ms-Genauigkeit minimal (verwenden SieStopwatch
Class, wenn Sie etwas genaueres benötigen).Thread.Sleep
Bindet Ihren Thread immer noch zusammen und gibtTask.Delay
ihn frei, um andere Arbeiten auszuführen, während Sie warten.quelle
Thread.Sleep()
verbraucht das Blockieren eines einzelnen Threads unnötigerweise einen gesamten Thread, der andernfalls anderweitig verwendet werden könnte. Wenn viele Aufgaben mit Thread.Sleep () ausgeführt werden, besteht eine hohe Wahrscheinlichkeit, dass alle Threadpool-Threads erschöpft sind und die Leistung ernsthaft beeinträchtigt wird.async
Methoden, da deren Verwendung empfohlen wird. Es ist im Grunde nur eine schlechte Idee,Thread.Sleep()
in einem Threadpool-Thread zu laufen, im Allgemeinen keine schlechte Idee. Immerhin gibt es,TaskCreationOptions.LongRunning
wenn man den (wenn auch entmutigten)Task.Factory.StartNew()
Weg geht.await wait
Tasl.Delay
verwendet den System-Timer. Da "Die Systemuhr" "mit einer konstanten Rate" tickt, beträgt die Tick-Geschwindigkeit des System-Timers etwa 16 ms. Jede von Ihnen angeforderte Verzögerung wird auf eine Anzahl von Ticks der Systemuhr gerundet, die um die Zeit bis zur ersten versetzt sind Tick.Task.Delay
Lesen Sie die msdn-Dokumentation unter docs.microsoft.com/en-us/dotnet/api/… und scrollen Sie nach unten zu den Anmerkungen.Wenn der aktuelle Thread beendet wird und Sie ihn verwenden
Thread.Sleep
und ausführen, erhalten Sie möglicherweise einenThreadAbortException
. Mit könnenTask.Delay
Sie jederzeit ein Stornierungszeichen bereitstellen und es ordnungsgemäß töten. Das ist ein Grund, warum ich wählen würdeTask.Delay
. Siehe http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspxIch stimme auch zu, dass Effizienz in diesem Fall nicht an erster Stelle steht.
quelle
await Task.Delay(5000)
. Wenn ich die Aufgabe töte, bekomme ich sieTaskCanceledException
(und unterdrücke sie), aber mein Thread lebt noch. Ordentlich! :)Ich möchte etwas hinzufügen. Eigentlich
Task.Delay
ist ein Timer-basierter Wartemechanismus. Wenn Sie sich die Quelle ansehen, finden Sie einen Verweis auf eineTimer
Klasse, die für die Verzögerung verantwortlich ist. Auf der anderen SeiteThread.Sleep
wird der aktuelle Thread tatsächlich in den Ruhezustand versetzt. Auf diese Weise blockieren und verschwenden Sie nur einen Thread. Im asynchronen Programmiermodell sollten Sie immer verwenden,Task.Delay()
wenn nach einer gewissen Verzögerung etwas (Fortsetzung) passieren soll.quelle