Wie ich es verstehe, wird Task.Yield
am Anfang einer Methode den Aufrufer zwingen weiterzumachen, wenn er nicht auf die Methode wartet. In der Zwischenzeit Task.Run
und ConfigureAwait(false)
beide Führen Sie einen Task für einen neuen Thread-Pool-Thread aus, wodurch der Aufrufer erneut gezwungen wird, fortzufahren, wenn er nicht auf die Methode wartet.
Ich kann den Unterschied zwischen Task.Yield
und dem Ausführen eines neuen Thread-Pool-Threads nicht verstehen, da direkt nach der Rückkehr zum Aufrufer der Rest der Methode weiter ausgeführt wird, was im Wesentlichen dasselbe ist. p>
In diesem Beitrag wird vorgeschlagen, dass Yield
und Task.Factory.StartNew
(was wirklich nur die alte Version von Task.Run
ist) ) kann synonym verwendet werden, was mir verwirrend erscheint.
Task.Yield
ist kein Ersatz für Task.Run
und hat nichts mit Task.ConfigureAwait
zu tun.
Task.Yield
- Erzeugt eine Warnung, die unmittelbar nach der Prüfung auf Vollständigkeit abgeschlossen wird. ConfigureAwait(false)
- Erzeugt eine Warnung von einer Aufgabe, die die erfasste SynchronizationContext
ignoriert. Task.Run
- Führt einen Delegaten für einen ThreadPool
-Thread aus. Task.Yield
unterscheidet sich von ConfigureAwait
darin, dass es sich um eine selbst erwartete Einheit handelt und nicht um einen konfigurierbaren Wrapper eines anderen erwarteten (d. h. Task
). Ein weiterer Unterschied besteht darin, dass Task.Yield
im erfassten Kontext fortgesetzt wird.
Task.Run
unterscheidet sich dann von beiden, da es nur einen Delegaten benötigt und auf dem ThreadPool
ausführt, Sie können es mit ConfigureAwait(false)
oder ohne verwenden.
Task.Yield
sollte verwendet werden, um einen asynchronen Punkt zu erzwingen, nicht als Ersatz für Task.Run
. Wenn in einer asynchronen Methode await erreicht wird, prüft es, ob die Aufgabe (oder eine andere Aufgabe) bereits abgeschlossen ist, und wenn dies der Fall ist, wird sie synchron fortgesetzt. Task.Yield
verhindert, dass dies passiert, daher ist es für Testzwecke nützlich.
Eine weitere Verwendung finden Sie in UI-Methoden, bei denen Sie nicht den einzelnen UI-Thread verwenden wollen, sondern einen asynchronen Punkt einfügen und der Rest zu einem späteren Zeitpunkt ausgeführt werden soll.
Task.Yield
wird auf dem aktuellen Synchronisationskontext oder auf dem aktuellen TaskScheduler
fortgesetzt, wenn einer vorhanden ist. Task.Run
macht das nicht. Es verwendet immer den Thread-Pool.
Zum Beispiel bleibt Task.Yield
im UI-Thread.
Vermeiden Sie Task.Yield
. Es ist Semantik weniger klar. Die verknüpfte Antwort ist ein Code-Geruch.
Tags und Links c# multithreading async-await asynchronous task