Ich denke, die Wahrheit ist selbst aus der Microsoft-Dokumentation nicht eindeutig:
In Visual Studio 2012 und .NET Framework 4.5 wird jede Methode, die dem async
Schlüsselwort ( Async
in Visual Basic) zugeordnet ist, als asynchrone Methode betrachtet, und die C # - und Visual Basic-Compiler führen die erforderlichen Transformationen durch, um die Methode mithilfe von TAP asynchron zu implementieren. Eine asynchrone Methode sollte entweder ein Task
oder ein Task<TResult>
Objekt zurückgeben.
http://msdn.microsoft.com/en-us/library/hh873177(v=vs.110).aspx
Das stimmt schon nicht. Jede Methode mit async
ist asynchron und sagt dann, dass sie entweder ein Task
oder zurückgeben sollte Task<T>
- was für Methoden am oberen Rand eines Aufrufstapels nicht richtig ist, z. B. Button_Click oder async void
.
Natürlich müssen Sie überlegen, worum es bei der Konvention geht.
Man könnte sagen, dass die Async
Suffix-Konvention darin besteht, dem API-Benutzer mitzuteilen, dass die Methode erwartet wird. Damit eine Methode erwartet werden kann, muss sie Task
für eine Leere oder Task<T>
für eine Methode zurückgegeben werden, die einen Wert zurückgibt. Dies bedeutet, dass nur die letztere mit einem Suffix versehen werden kann Async
.
Oder Sie könnten sagen, dass die Async
Suffix-Konvention darin besteht, zu kommunizieren, dass die Methode sofort zurückkehren kann, den aktuellen Thread freizugeben, um andere Arbeiten auszuführen, und möglicherweise Rennen zu verursachen.
In diesem Microsoft-Dokumentzitat heißt es:
Konventionell hängen Sie "Async" an die Namen von Methoden an, die einen Async- oder Async-Modifikator haben.
http://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_NamingConvention
Was nicht einmal erwähnt, dass Ihre eigenen asynchronen Methoden, die zurückkehren, Task
das Async
Suffix benötigen , dem wir uns alle einig sind.
Die Antwort auf diese Frage könnte also lauten: beides. In beiden Fällen müssen Sie Async
Methoden mit dem async
Schlüsselwort anhängen , die Task
oder zurückgeben Task<T>
.
Ich werde Stephen Toub bitten, die Situation zu klären.
Aktualisieren
So tat ich. Und hier ist, was unser guter Mann schrieb:
Wenn eine öffentliche Methode Task zurückgibt und asynchroner Natur ist (im Gegensatz zu einer Methode, die bekanntermaßen immer synchron zum Abschluss ausgeführt wird, aber aus irgendeinem Grund immer noch eine Task zurückgibt), sollte sie das Suffix "Async" haben. Das ist die Richtlinie. Das Hauptziel bei der Benennung besteht darin, dem Verbraucher die Funktionalität klar zu machen, dass die aufgerufene Methode wahrscheinlich nicht alle Arbeiten synchron abschließt. Dies hilft natürlich auch in Fällen, in denen die Funktionalität sowohl mit synchronen als auch mit asynchronen Methoden verfügbar gemacht wird, sodass Sie einen Namensunterschied benötigen, um sie zu unterscheiden. Wie die Methode ihre asynchrone Implementierung erreicht, spielt für die Benennung keine Rolle: ob async / await verwendet wird, um die Hilfe des Compilers zu erhalten, oder ob Typen und Methoden von System.Threading.Tasks direkt verwendet werden (e. G. TaskCompletionSource) spielt keine Rolle, da dies die Signatur der Methode für einen Konsumenten der Methode nicht beeinflusst.
Natürlich gibt es immer Ausnahmen von einer Richtlinie. Am bemerkenswertesten bei der Benennung sind Fälle, in denen die Existenzberechtigung eines ganzen Typs darin besteht, asynchrone Funktionen bereitzustellen. In diesem Fall wäre es übertrieben, Async für jede Methode zu haben, z. B. die Methoden für Task selbst, die andere Tasks erzeugen .
Bei asynchronen Methoden mit ungültiger Rückgabe ist es nicht wünschenswert, diese im öffentlichen Bereich zu haben, da der Anrufer nicht genau wissen kann, wann die asynchrone Arbeit abgeschlossen ist. Wenn Sie jedoch eine asynchrone Methode mit ungültiger Rückgabe öffentlich verfügbar machen müssen, möchten Sie wahrscheinlich einen Namen haben, der anzeigt, dass asynchrone Arbeit initiiert wird, und Sie könnten hier das Suffix "Async" verwenden, wenn dies sinnvoll ist. Angesichts der Seltenheit dieses Falls würde ich behaupten, dass es sich wirklich um eine Einzelfallentscheidung handelt.
Ich hoffe das hilft, Steve
Die prägnante Anleitung aus Stephens Eröffnungssatz ist klar genug. Es wird ausgeschlossen, async void
weil es ungewöhnlich ist, eine öffentliche API mit einem solchen Design erstellen zu wollen, da die korrekte Implementierung einer asynchronen Leere darin besteht, eine einfache Task
Instanz zurückzugeben und den Compiler seiner Magie zu überlassen. Wenn Sie jedoch eine wollten public async void
, wird das Anhängen Async
empfohlen. Andere Top-of-Stack- async void
Methoden wie Event-Handler sind normalerweise nicht öffentlich und spielen keine Rolle.
Für mich bedeutet dies, dass ich, wenn ich mich über das Suffixieren Async
eines frage async void
, es wahrscheinlich in ein Suffix umwandeln sollte, async Task
damit Anrufer darauf warten und dann anhängen können Async
.