Penso che la verità sia ambigua anche dalla documentazione di Microsoft:
In Visual Studio 2012 e .NET Framework 4.5, qualsiasi metodo attribuito con la async
parola chiave ( Async
in Visual Basic) è considerato un metodo asincrono ei compilatori C # e Visual Basic eseguono le trasformazioni necessarie per implementare il metodo in modo asincrono utilizzando TAP. Un metodo asincrono dovrebbe restituire a Task
o un Task<TResult>
oggetto.
http://msdn.microsoft.com/en-us/library/hh873177(v=vs.110).aspx
Non è già così. Qualsiasi metodo con async
è asincrono e quindi sta dicendo che dovrebbe restituire un Task
o Task<T>
- che non è corretto per i metodi nella parte superiore di uno stack di chiamate, Button_Click per esempio, o async void
.
Certo, devi considerare qual è il punto della convenzione?
Si potrebbe dire che la Async
convenzione del suffisso è di comunicare all'utente API che il metodo è in attesa. Affinché un metodo sia attendibile, deve restituire Task
un valore void o Task<T>
un metodo di restituzione del valore, il che significa che solo quest'ultimo può essere suffisso con Async
.
Oppure potresti dire che la Async
convenzione del suffisso è di comunicare che il metodo può tornare immediatamente, abbandonando il thread corrente per eseguire altri lavori e potenzialmente causando gare.
Questa citazione di Microsoft doc dice:
Per convenzione, aggiungi "Async" ai nomi dei metodi che hanno un modificatore Async o async.
http://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_NamingConvention
Il che non menziona nemmeno che i tuoi metodi asincroni che restituiscono Task
necessitano del Async
suffisso, cosa che penso siamo tutti d'accordo che lo facciano.
Quindi la risposta a questa domanda potrebbe essere: entrambe. In entrambi i casi, è necessario aggiungere Async
ai metodi con la async
parola chiave e che restituiscono Task
o Task<T>
.
Chiederò a Stephen Toub di chiarire la situazione.
Aggiornare
Così ho fatto. Ed ecco cosa ha scritto il nostro brav'uomo:
Se un metodo pubblico restituisce attività ed è di natura asincrona (al contrario di un metodo noto per essere eseguito sempre in modo sincrono fino al completamento, ma restituisce comunque un'attività per qualche motivo), dovrebbe avere un suffisso "Async". Questa è la linea guida. L'obiettivo principale qui con la denominazione è rendere molto ovvio a un consumatore della funzionalità che il metodo invocato probabilmente non completerà tutto il suo lavoro in modo sincrono; ovviamente aiuta anche nel caso in cui la funzionalità sia esposta con metodi sia sincroni che asincroni in modo tale che sia necessaria una differenza di nome per distinguerli. Il modo in cui il metodo raggiunge la sua implementazione asincrona è irrilevante per la denominazione: se async / await viene utilizzato per ottenere l'aiuto del compilatore o se i tipi ei metodi da System.Threading.Tasks vengono utilizzati direttamente (ad es. g. TaskCompletionSource) non ha molta importanza, in quanto ciò non influisce sulla firma del metodo per quanto riguarda un consumatore del metodo.
Naturalmente, ci sono sempre eccezioni a una linea guida. Il più degno di nota nel caso della denominazione sarebbero i casi in cui la ragion d'essere di un intero tipo è di fornire funzionalità focalizzate sull'asincronia, nel qual caso avere Async su ogni metodo sarebbe eccessivo, ad esempio i metodi su Task stesso che producono altri Task .
Per quanto riguarda i metodi asincroni che restituiscono il vuoto, non è desiderabile averli nell'area di superficie pubblica, poiché il chiamante non ha un buon modo per sapere quando il lavoro asincrono è stato completato. Se devi esporre pubblicamente un metodo asincrono che restituisce un valore nullo, probabilmente vorrai avere un nome che comunichi che è stato avviato il lavoro asincrono e potresti usare il suffisso "Async" qui se ha senso. Dato quanto raro dovrebbe essere questo caso, direi che è davvero un tipo di decisione caso per caso.
Spero che questo aiuti, Steve
La breve guida della frase di apertura di Stephen è abbastanza chiara. Esclude async void
perché è insolito voler creare un'API pubblica con un tale design poiché il modo corretto per implementare un vuoto asincrono è restituire Task
un'istanza semplice e lasciare che il compilatore faccia la sua magia. Tuttavia, se si desidera un public async void
, Async
è consigliabile aggiungerlo . Altri async void
metodi top-of-stack come i gestori di eventi di solito non sono pubblici e non sono importanti / qualificati.
Per me, mi dice che se mi trovo a chiedermi se aggiungere Async
un suffisso async void
, probabilmente dovrei trasformarlo in un in async Task
modo che i chiamanti possano aspettarlo, quindi aggiungere Async
.