2016-06-24 17 views
12

Schnell Frage ..„async Aufgabe warten dann Aufgabe“ vs „Task dann Aufgabe zurückkehren“

Um eine solide Basis Verständnis über die asynchrone Programmierung und der await Ich mag würde kennen lernen, was der Unterschied zwischen diesen ist zwei Code-Snippets, wenn es um Multi-Threading und die Ausführungsreihenfolge und die Zeit kommt:

diese:

public Task CloseApp() 
{ 
     return Task.Run(
         ()=>{ 
           // save database 
           // turn off some lights 
           // shutdown application 
          }); 
} 

Versus dies:

public async Task CloseApp() 
{ 
     await Task.Run(
         ()=>{ 
           // save database 
           // turn off some lights 
           // shutdown application 
          }); 
} 

, wenn ich es in dieser Routine nenne:

private async void closeButtonTask() 
{ 
    // Some Task 1 
    // .. 

    await CloseApp(); 

    // Some Task 2 
    // .. 
} 
+1

Sie haben feine Unterschiede in der Art und Weise, wie Ausnahmen umgebrochen werden – SLaks

+0

Mögliche dupe http://stackoverflow.com/questions/21033150/any-difference-between-await-task-run-return-and-return-task-run – DavidG

Antwort

11

Es ist fast das gleiche (in Bezug auf Threads usw.). Aber für den zweiten (mit await) wird viel mehr Overhead vom Compiler erstellt.

Methods deklariert als async und await Verwendung in einer Maschine Zustand umgewandelt durch den Compiler. Wenn Sie also die await drücken, wird der Kontrollfluss an die aufrufende Methode zurückgegeben und die Ausführung Ihrer async Methode wird nach der await fortgesetzt, wenn die erwartete Task beendet ist.

Da nach Ihrer await kein Code mehr vorhanden ist, müssen Sie await sowieso nicht verwenden. Einfach zurückgeben Task ist genug.

+0

* "Wenn Sie die Wartezeit erreichen, wird der Kontrollfluss an die aufrufende Methode zurückgegeben" * - Der Kontrollfluss ** kann ** an die aufrufende Methode zurückgegeben werden, insbesondere wird er nicht zurückgegeben, wenn die erwartete Aufgabe bereits abgeschlossen ist . – acelent

+0

@acelent thx für das Detail, nie darüber nachgedacht, was passiert, wenn die Aufgabe bereits abgeschlossen ist. Ich kenne die genauen Details nicht, was der Compiler Zeile für Zeile macht. –

4

Es gibt sehr wenige Unterschiede zwischen den beiden Ansätzen. Im Grunde teilen sie die gleiche Semantik. Die Version mit async/await umschließt jedoch die Ausführung der inneren Task in einer äußeren vom Compiler generierten Task. Die nicht-asynchrone Version nicht. Daher ist die nicht-asynchrone Version (sehr marginal) effizienter.

+0

* "Die nicht-asynchrone Version ist (sehr marginal) effizienter." * - Das hängt davon ab, ob die async/await-Version merklichen Müll erzeugt, wenn die Methode sehr oft aufgerufen wird: die Zustandsmaschine und eine andere Aufgabe. – acelent

+0

@acelent: eine Generation generieren 0 Müll fühlt sich immer noch ziemlich marginal an – Falanwe

+0

Ok, ich möchte nur darauf hinweisen, dass das nicht immer der Fall für alle ist ([1] (https://msdn.microsoft.com/en-us) /magazine/hh456402.aspx)), und Sie können sich nicht darauf verlassen, dass Aufgaben oder Verweise auf Aufgaben so ephemer sind ([2] (https://channel9.msdn.com/Events/Build/BUILD2011/TOOL-829T) , [um 0:25:40] (https://channel9.msdn.com/Events/Build/BUILD2011/TOOL-829T#time=25m40s), [um 0:30:20] (https: // channel9. msdn.com/Events/Build/BUILD2011/TOOL-829T#time=30m20s)). – acelent