2016-06-24 20 views
12

Domanda veloce .."async Task allora attendono Task" vs "Task poi tornare compito"

Al fine di ottenere una certa comprensione solida base su Asynchronous programmazione e la await vorrei sapere qual è la differenza tra questi due frammenti di codice quando si tratta di multi filettatura e la sequenza di esecuzione e di tempo:

questo:

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

Versus questo:

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

se sto chiamando in questa routine:

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

    await CloseApp(); 

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

Hanno sottili differenze nel modo in cui le eccezioni sono avvolti – SLaks

+0

possibile vittima http://stackoverflow.com/questions/21033150/any-difference-between-await-task-run-return-and-return-task-run – DavidG

risposta

11

È quasi la stessa (in termini di thread, ecc.). Ma per il secondo (usando await) verrà creato molto più overhead dal compilatore.

metodi dichiarati come async e utilizzando await vengono convertiti in una macchina Stato dal compilatore. Pertanto, quando si preme await, il flusso di controllo viene restituito al metodo di chiamata e l'esecuzione del metodo async viene ripresa dopo lo await quando l'attesa Task è terminata.

Poiché non c'è più codice dopo il await, non è necessario utilizzare await. Basta restituire il Task è sufficiente.

+0

* "quando si attendono l'attesa, il flusso di controllo viene restituito al metodo di chiamata" * - Il flusso di controllo ** potrebbe essere restituito al metodo di chiamata, in particolare non verrà restituito quando l'attività attesa è già completa . – acelent

+0

@acelent thx per i dettagli, mai pensato a cosa succede quando l'attività è già finita. Non conosco i dettagli esatti di ciò che il compilatore fa linea per riga. –

4

Ci sono poche differenze tra i due approcci. Fondamentalmente, condividono la stessa semantica. Tuttavia, la versione con async/attendi esegue l'esecuzione dell'attività interna in un'attività generata dal compilatore esterno. La versione non asincrona no. Pertanto, la versione non asincrona è (molto marginalmente) più efficiente.

+0

* "la versione non asincrona è (molto marginalmente) più efficiente." * - Dipende, se il metodo viene chiamato molto spesso, quindi la versione asincrona/attesa potrebbe generare spazzatura evidente: la macchina a stati e un'altra attività. – acelent

+0

@acelent: generare un po 'di spazzatura di generazione 0 mi sembra ancora piuttosto marginale – Falanwe

+0

Ok, voglio solo precisare che non è sempre il caso per tutti ([1] (https://msdn.microsoft.com/en-us /magazine/hh456402.aspx)), e non è possibile affidarsi a compiti o riferimenti a compiti che siano effimeri ([2] (https://channel9.msdn.com/Events/Build/BUILD2011/TOOL-829T) , [alle 0:25:40] (https://channel9.msdn.com/Events/Build/BUILD2011/TOOL-829T#time=25m40s), [alle 0:30:20] (https: // channel9. msdn.com/Events/Build/BUILD2011/TOOL-829T#time=30m20s)). – acelent