Le risposte di SLaks e Killercam sono buone; Ho pensato di aggiungere solo un po 'più di contesto.
La tua prima domanda riguarda essenzialmente quali metodi possono essere contrassegnati async
.
Un metodo contrassegnato come async
può restituire void
, Task
oppure Task<T>
. Quali sono le differenze tra loro?
È Task<T>
possibile attendere un metodo asincrono di ritorno e quando l'attività viene completata, viene offerto un T.
È Task
possibile attendere un metodo asincrono di ritorno e al termine dell'attività è pianificata l'esecuzione della continuazione dell'attività.
Un void
metodo asincrono ritorno non può essere atteso; è un metodo "spara e dimentica". Funziona in modo asincrono e non hai modo di dire quando è fatto. Questo è più che un po 'strano; come dice SLaks, normalmente lo faresti solo quando crei un gestore di eventi asincrono. L'evento si attiva, il gestore esegue; nessuno "attenderà" l'attività restituita dal gestore eventi perché i gestori eventi non restituiscono attività e, anche se lo facessero, quale codice userebbe l'attività per qualcosa? Di solito non è il codice utente che trasferisce il controllo al gestore.
La tua seconda domanda, in un commento, riguarda essenzialmente ciò che può essere await
ed:
Quali tipi di metodi possono essere modificati await
? È possibile modificare un metodo di ritorno del vuoto await
?
No, non è possibile attendere un metodo di ritorno del vuoto. Il compilatore si traduce await M()
in una chiamata a M().GetAwaiter()
, dove GetAwaiter
potrebbe essere un metodo di istanza o un metodo di estensione. Il valore atteso deve essere uno per il quale è possibile ottenere un cameriere; chiaramente un metodo di ritorno del vuoto non produce un valore da cui è possibile ottenere un cameriere.
Task
i metodi di ritorno possono produrre valori attendibili. Prevediamo che terze parti vorranno creare le proprie implementazioni di Task
oggetti simili che possono essere attesi e che sarete in grado di aspettarli. Tuttavia, non ti sarà permesso di dichiarare async
metodi che restituiscono altro che void
, Task
o Task<T>
.
(AGGIORNAMENTO: la mia ultima frase potrebbe essere falsata da una versione futura di C #; esiste una proposta per consentire tipi di ritorno diversi dai tipi di attività per i metodi asincroni.)
(AGGIORNAMENTO: la funzionalità sopra menzionata è arrivata a C # 7.)