Was ist der Unterschied zwischen Task.Yield, Task.Run und ConfigureAwait (false)?

8

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.

    
James Ko 04.07.2015, 15:00
quelle

2 Antworten

6

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.

    
i3arnon 04.07.2015, 19:40
quelle
5

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.

    
usr 04.07.2015 16:47
quelle