Was ist die Konvention zum Suffixieren von Methodennamen mit "Async"?
Sollte das Suffix "Async" nur an eine Methode angehängt werden, die mit dem async
Modifikator deklariert wurde ?
public async Task<bool> ConnectAsync()
Oder reicht es aus, dass die Methode nur zurückgibt Task<T>
oder Task
?
public Task<bool> ConnectAsync()
c#
.net
async-await
naming-conventions
naming
kasperhj
quelle
quelle
Antworten:
Ich denke, die Wahrheit ist selbst aus der Microsoft-Dokumentation nicht eindeutig:
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 einTask
oder zurückgeben sollteTask<T>
- was für Methoden am oberen Rand eines Aufrufstapels nicht richtig ist, z. B. Button_Click oderasync 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 sieTask
für eine Leere oderTask<T>
für eine Methode zurückgegeben werden, die einen Wert zurückgibt. Dies bedeutet, dass nur die letztere mit einem Suffix versehen werden kannAsync
.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:
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
dasAsync
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 demasync
Schlüsselwort anhängen , dieTask
oder zurückgebenTask<T>
.Ich werde Stephen Toub bitten, die Situation zu klären.
Aktualisieren
So tat ich. Und hier ist, was unser guter Mann schrieb:
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 einfacheTask
Instanz zurückzugeben und den Compiler seiner Magie zu überlassen. Wenn Sie jedoch eine wolltenpublic async void
, wird das AnhängenAsync
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 frageasync void
, es wahrscheinlich in ein Suffix umwandeln sollte,async Task
damit Anrufer darauf warten und dann anhängen könnenAsync
.quelle
PersonString
oderPriceDecimal
warumGetAsync
- API-Konsumenten von asynchronen APIs müssen sich darüber keine Gedanken machen, da die Anforderung immer zurückgegeben wird, nachdem alle Aufgaben ohnehin abgeschlossen sind. Es ist albern und nervt mich wirklich. Aber es ist nur eine andere Konvention, von der niemand wirklich weiß, warum sie dort ist.Ich erstelle viele API-Dienste und andere Anwendungen, die andere Systeme aufrufen, auf denen der größte Teil meines Codes asynchron ausgeführt wird.
Meine eigene Faustregel, der ich folge, lautet:
Beispiele:
Nur eine Methode:
Gleiche Methode mit zwei Signaturen:
Dies ist sinnvoll, da dieselben Daten zurückgegeben werden, aber das einzige, was sich unterscheidet, ist die Art der Rückgabe von Daten , nicht die Daten selbst.
Ich denke auch, dass diese Namenskonventionen aufgrund der Notwendigkeit existieren, asynchrone Methoden einzuführen und dennoch die Abwärtskompatibilität aufrechtzuerhalten.
Ich behaupte, dass neuer Code nicht das Async-Suffix verwenden sollte. Es ist genauso offensichtlich wie der Rückgabetyp von String oder Int, wie zuvor in diesem Thread erwähnt.
quelle
Das aufgabenbasierte asynchrone Muster (TAP) schreibt vor, dass Methoden immer ein
Task<T>
(oderTask
) zurückgeben und mit einem asynchronen Suffix benannt werden sollen. Dies ist unabhängig von der Verwendung vonasync
. BeideTask<bool> Connect()
und werden gut kompiliert und ausgeführt, aber Sie werden die TAP-Namenskonvention nicht befolgen.async
Task<bool> Connect()
Wenn der Hauptteil der Methode (unabhängig vom Rückgabetyp oder -namen) enthält
await
, müssen Sie Folgendes verwendenasync
: und der Compiler teilt Ihnen mit, dass der Operator 'await' nur innerhalb einer asynchronen Methode verwendet werden kann. ... ". RückgabeTask<T>
oderTask
ist nicht "genug", um die Verwendung zu vermeidenasync
. Weitere Informationen finden Sie unter Async (C # -Referenz) .Beides und befolgen Sie die TAP-Konventionen ordnungsgemäß. Sie könnten immer das Schlüsselwort verwenden, aber Sie erhalten eine Compiler-Warnung "Diese asynchrone Methode hat keine 'wait'-Operatoren und wird synchron ausgeführt. ...", wenn der Body dies nicht verwendet .
async
Task<bool> ConnectAsync()
Task<bool> ConnectAsync()
async
await
quelle
async
Schlüsselwort verwenden.async
wird oder nicht, ist der zweite Teil der Frage.async
Modifikator verwendet werden soll oder nicht . Siehe auch OP-Beispielepublic async Task<bool> ConnectAsync()
(mitasync
Modifikator) vspublic Task<bool> ConnectAsync()
(ohneasync
Modifikator). Die Methode Name selbst hat das Suffix „Async“ in beiden Fällen.Task
oder Methoden mit angehängten Methoden angehängt werden sollasync Task
.Das. Das
async
Schlüsselwort ist hier nicht das eigentliche Problem. Wenn Sie die Asynchronität implementieren, ohne die zu verwendenasync
Schlüsselworts , lautet die Methode im allgemeinen Sinne immer noch "Async".quelle
Da
Task
undTask<T>
beide zu erwartende Typen sind, repräsentieren sie einige asynchrone Operation. Oder zumindest sollten sie darstellen.Sie sollten
Async
einer Methode ein Suffix hinzufügen , das in einigen Fällen (nicht unbedingt allen) keinen Wert zurückgibt, sondern einen Wrapper für einen laufenden Vorgang zurückgibt. Dieser Wrapper ist normalerweise einTask
, aber unter Windows RT kann es seinIAsyncInfo
. Folgen Sie Ihrem Bauchgefühl und denken Sie daran, wenn ein Benutzer Ihres Codes das siehtAsync
Funktion , weiß, dass der Aufruf dieser Methode vom Ergebnis dieser Methode entkoppelt ist und dass er entsprechend handeln muss.Beachten Sie, dass es Methoden wie
Task.Delay
und gibt,Task.WhenAll
die zurückgebenTask
und die noch nicht habenAsync
Suffix haben.Beachten Sie auch, dass es
async void
Methoden gibt , die eine asynchrone Methode zum Feuern und Vergessen darstellen , und Sie sollten sich besser darüber im Klaren sein, dass die Methode auf diese Weise erstellt wurde.quelle
Ich würde argumentieren, dass es das Async-Suffix verwenden sollte, wenn es eine Task zurückgibt, unabhängig davon, ob die Methode mit dem deklariert ist
async
Modifikator oder nicht.Der Grund dafür ist, dass der Name in der Schnittstelle deklariert ist. Die Schnittstelle deklariert den Rückgabetyp a
Task
. Dann gibt es zwei Implementierungen dieser Schnittstelle, eine Implementierung implementiert sie unter Verwendung desasync
Modifikators, die andere nicht.quelle
In der asynchronen Programmierung mit asynchronem und warten (C #) bietet Microsoft die folgenden Anleitungen an:
Ich finde diese Anleitung unvollständig und unbefriedigend. Bedeutet dies, dass in Abwesenheit des
async
Modifikators diese MethodeConnect
anstelle von benannt werden sollteConnectAsync
?Das glaube ich nicht. Wie in der angegebenen prägnanten Antwort von @Servy und der weiteren detaillierten Antwort von @Luke Puplett , glaube ich , dass es angemessen ist , und in der Tat zu erwarten , dass diese Methode soll benannt werden
ConnectAsync
(weil es eine awaitable zurückzugibt). Zur weiteren Unterstützung wird @John Skeet in dieser Antwort auf eine andere FrageAsync
unabhängig vom Vorhandensein desasync
Modifikators an den Methodennamen angehängt .Betrachten Sie abschließend bei einer anderen Frage diesen Kommentar von @Damien_The_Unbeliever :
Daraus schließe ich, dass es die asynchrone Natur der Methode ist , die vorschreibt, wie sie benannt werden soll. Der Benutzer der Methode weiß nicht einmal, ob der
async
Modifikator in seiner Implementierung verwendet wird (ohne den C # -Quellcode oder CIL).quelle