L'utilisation du suffixe "Async" dans un nom de méthode dépend-elle de l'utilisation du modificateur 'async'?

Quelle est la convention pour suffixer les noms de méthodes avec "Async"?

Le suffixe "Async" devrait-il être ajouté uniquement à une méthode déclarée avec le modificateur async?

public async Task<bool> ConnectAsync()

, Ou suffit-il que la méthode retourne Task<T> ou Task?

public Task<bool> ConnectAsync()
63
demandé sur DavidRR 2013-04-11 18:44:06

7 réponses

Je pense que la vérité est ambiguë même à partir de la documentation de Microsoft:

Dans Visual Studio 2012 et. NET Framework 4.5, toute méthode attribué avec le mot clé async (Async Dans Visual Basic) est considéré comme une méthode asynchrone, et le C# et Visual Basic les compilateurs effectuent les transformations nécessaires pour implémenter le méthode asynchrone en utilisant TAP. Une méthode asynchrone devrait renvoyer Task ou Task<TResult> objet.

Http://msdn.microsoft.com/en-us/library/hh873177(v=vs. 110).aspx

Ce n'est pas déjà juste. Toute méthode avec async est asynchrone et ensuite il dit qu'il devrait retourner soit un Task ou Task<T> - ce qui n'est pas bon pour les méthodes en haut d'une pile d'appels, Button_Click par exemple, ou async void.

Bien sûr, vous devez considérer quel est le point de la convention?

Vous pourriez dire que la convention de suffixe Async est de communiquer à L'utilisateur de L'API que la méthode est attendue. Pour qu'une méthode soit attendue, elle doit renvoyer Task pour un void, ou Task<T> pour une méthode de retour de valeur, ce qui signifie que seule cette dernière peut être suffixée avec Async.

Ou vous pourriez dire que la convention de suffixe Async est de communiquer que la méthode peut retourner immédiatement, abandonnant le thread en cours pour effectuer d'autres travaux et potentiellement provoquer des courses.

Cette citation de Microsoft doc dit:

Par convention, vous ajouter "Async" aux noms des méthodes qui ont un Modificateur asynchrone ou asynchrone.

Http://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_NamingConvention

Qui ne mentionne même pas que vos propres méthodes asynchrones renvoyant Task ont besoin du suffixe Async, ce que je pense que nous sommes tous d'accord.


Donc, la réponse à cette question pourrait être: les deux. Dans les deux cas, vous devez ajouter Async aux méthodes avec le mot-clé async et renvoyer Task ou Task<T>.


Je vais demander à Stephen Toub de clarifier la situation.

Mise à Jour

Donc je l'ai fait. Et voici ce que notre bon homme a écrit:

Si une méthode publique renvoie une tâche et est de nature asynchrone (comme opposé à une méthode qui est connue pour s'exécuter toujours de manière synchrone pour d'achèvement, mais renvoie toujours une Tâche pour une raison quelconque), il devrait avoir un suffixe "asynchrone". C'est la ligne directrice. L'objectif principal ici avec le nom est pour le rendre très évident pour un consommateur de la fonctionnalité que la méthode invoquée ne sera probablement pas terminée tout son travail de manière synchrone; il aide bien sûr aussi avec le cas où la fonctionnalité est exposée à la fois synchrone et asynchrone méthodes telles que vous avez besoin d'une différence de nom pour les distinguer. Comment la méthode réalise son implémentation asynchrone est sans importance pour la dénomination: si async / await est utilisé pour obtenir l'aide du compilateur, ou si les types et les méthodes de Système.Le filetage.Les tâches sont utilisées directement (par exemple TaskCompletionSource) n'a pas vraiment d'importance, car cela n'affecte pas la signature de la méthode en ce qui concerne un consommateur du la méthode est concerné.

Bien sûr, il y a toujours des exceptions à un directive. Le plus notable dans le cas de la dénomination serait cases où la raison d'être d'un type entier est de fournir fonctionnalité, auquel cas avoir Async sur chaque méthode serait overkill, par exemple, l' méthodes sur la Tâche elle-même qui produisent d'autres Tâches.

En ce qui concerne les méthodes asynchrones de retour de vide, il n'est pas souhaitable d'avoir ceux dans la surface publique, puisque l'appelant n'a pas de bon moyen de savoir quand le travail asynchrone est terminée. Si vous devez exposer une méthode asynchrone de retour vide publiquement, cependant, vous le faites probablement envie d'avoir un nom qui indique que le travail asynchrone est initié, et vous pouvez utiliser le suffixe "Async" ici si cela avait du sens. Donné comme ce cas devrait être rare, je dirais que c'est vraiment un cas par cas, la nature de la décision.

J'espère que ça aide, Steve

L'orientation succincte de la phrase d'ouverture de Stephen est assez claire. Il exclut async void car il est inhabituel de vouloir créer une API publique avec une telle conception puisque la bonne façon d'implémenter un vide asynchrone est de retourner une instance Task simple et de laisser le compilateur à sa magie. Cependant, si vous vouliez un public async void, alors l'ajout de Async est aviser. Les autres méthodes async void en haut de la pile, telles que les gestionnaires d'événements, ne sont généralement pas publiques et n'ont pas d'importance/de qualification.

Pour moi, il me dit que si je me pose des questions sur le suffixe Async sur un async void, je devrais probablement le transformer en async Task afin que les appelants puissent l'attendre, puis ajouter Async.

79
répondu Luke Puplett 2014-07-08 18:24:18

Quelle est la convention pour suffixer les noms de méthode avec "Async".

Le modèle asynchrone basé sur les tâches (TAP) dicte que les méthodes doivent toujours renvoyer un Task<T> (ou Task) et être nommées avec un suffixeasync ; ceci est séparé de l'utilisation de async. Task<bool> Connect() et asyncTask<bool> Connect() compilera et fonctionnera très bien, mais vous ne suivrez pas la convention de nommage du robinet.

Si la méthode contient le modificateur async, ou il suffit qu'il retourne juste la tâche?

Si le corps de la méthode (quel que soit le type ou le nom de retour) inclut await, Vous devez utiliser async; et le compilateur vous dira "L'opérateur 'await' ne peut être utilisé que dans une méthode asynchrone. ...". Renvoyer Task<T> ou Task n'est pas "suffisant" pour éviter d'utiliser async. Voir async (référence C#) pour plus de détails.

C'est-à-dire laquelle de ces signatures est correcte:

Les Deux asyncTask<bool> ConnectAsync() et Task<bool> ConnectAsync() suivent correctement le ROBINET conventions. Vous pouvez toujours utiliser le mot-clé async, mais vous obtiendrez un avertissement du compilateur "cette méthode asynchrone manque d'opérateurs' await ' et s'exécutera de manière synchrone. ..."si le corps n'utilise pas await.

20
répondu Ðаn 2015-04-27 14:22:57

Ou assez qu'il retourne juste la tâche?

Ça. Le mot clé async n'est pas le vrai problème ici. Si vous implémentez l'asynchronie sans utiliser le mot clé async, la méthode est toujours "asynchrone", au sens général.

10
répondu Servy 2013-04-11 14:47:21

Puisque Task et Task<T>sont tous deux des types awaitable, ils représentent certaines opérations asynchrones. Ou au moins qu'ils sont censés représenter.

Vous devez ajouter le suffixe Async à une méthode qui, dans certains cas (pas nécessairement tous), ne renvoie pas de valeur mais renvoie plutôt un wrapper autour d'une opération en cours. Ce wrapper est généralement un Task, mais sous Windows RT il peut être IAsyncInfo. Suivez votre intuition et rappelez-vous que si un utilisateur de votre code voit la fonction Async, il le fera savoir que l'invocation de cette méthode est découplé du résultat de cette méthode et qu'ils doivent agir en conséquence.

Notez qu'il existe des méthodes telles que Task.Delay et Task.WhenAll qui renvoient Task sans avoir le suffixe Async.

Notez également qu'il existe des méthodes async void qui représentent fire et forget méthode asynchrone et vous devriez mieux être conscient que la méthode est construite de cette manière.

7
répondu Toni Petrina 2013-04-11 14:54:00

Je construis beaucoup de Services API et d'autres applications qui appellent d'autres systèmes où la plupart de mon code est en cours d'exécution asynchrone.

Ma propre règle de base que je suis est:

S'il existe à la fois une méthode non-asynchrone et une méthode asynchrone qui renvoient la même chose Je suffixe l'async avec Async. Pas autrement.

Exemples:

Une seule méthode:

public async Task<User> GetUser() { [...] }

Même méthode avec deux signatures:

public User GetUser() { [...] }

public async Task<User> GetUserAsync() { [...] }

Cela a du sens puisque ce sont les mêmes données cela est retourné mais la seule chose qui diffère est la façon de renvoyer les données , pas les données elles-mêmes.

Je pense aussi que ces conventions de nommage existent en raison de la nécessité d'introduire des méthodes asynchrones et de maintenir une compatibilité ascendante.

Je soutiens que le nouveau code ne devrait pas utiliser le suffixe asynchrone. C'est tout aussi évident que le type de chaîne de retour, ou Int comme mentionné précédemment dans ce thread.

6
répondu Jonas Stensved 2017-12-14 10:19:45

Dans La programmation asynchrone avec async et await (C#) , Microsoft offre les conseils suivants:

Convention De Nommage

Par convention, vous ajoutez "Async" aux noms des méthodes qui ont un async modificateur.

Vous pouvez ignorer la convention où un événement, une classe de base ou une interface contrat suggère un nom différent. Par exemple, vous ne devriez pas renommer gestionnaires d'événements courants, tels que Button1_Click.

Je trouve cette orientation incomplète et insatisfaisante. Cela signifie-t-il qu'en l'absence du modificateur async, cette méthode devrait être nommée Connect au lieu de ConnectAsync?

public Task<bool> ConnectAsync()
{
    return ConnectAsyncInternal();
}

Je ne pense pas. Comme indiqué dans la réponse concise par @ Servy {[14] } et plus réponse détaillée par @ Luke Puplett , je crois qu'il est approprié et en effet attendu que cette méthode devrait {[40] } être nommée ConnectAsync (car elle renvoie un awaitable). À l'appui de cela, @ John Skeet dans cette réponse à une autre question ajoute Async au nom de la méthode indépendamment de la présence du modificateur async.

Enfin, sur une autre question, considérons ce commentaire par @Damien_The_Unbeliever:

async/await sont mise en œuvre détails de vos méthodes. C'est important pas un seul mot si votre méthode est déclarée async Task Method() ou juste Task Method(), pour autant que votre appelants sont concernés. (Dans fait, vous êtes libre de changer entre ces deux plus tard temps sans qu'il soit considéré comme un changement de rupture.)

De là, je déduis que c'est la nature asynchrone de la méthode qui dicte comment elle doit être nommée. L'utilisateur de la méthode ne saura même pas si le modificateur async est utilisé dans son implémentation (sans le code source C# ou CIL).

4
répondu DavidRR 2017-05-23 11:47:19

Je dirais qu'il devrait utiliser le suffixe Async s'il renvoie une tâche indépendamment du fait que la méthode soit déclarée avec le modificateur async.

La raison derrière cela étant que le nom est déclaré dans l'interface. L'interface déclare le type de retour qui est un Task. Ensuite, il y a deux implémentations de cette interface, une implémentation l'implémente en utilisant le modificateur async, l'autre Non.

public interface IFoo
{
    Task FooAsync();
}

public class FooA : IFoo
{
    public Task FooAsync() { /* ... */ }
}

public class FooB : IFoo
{
    public async Task FooAsync() { /* ... */ }
}
1
répondu Fred 2016-06-17 13:56:18