Qual é a convenção para sufixar nomes de método com "Async"?
O sufixo "Async" deve ser acrescentado apenas a um método declarado com o async
modificador?
public async Task<bool> ConnectAsync()
Ou basta que o método apenas retorne Task<T>
ou Task
?
public Task<bool> ConnectAsync()
c#
.net
async-await
naming-conventions
naming
Kasperhj
fonte
fonte
Respostas:
Acho que a verdade é ambígua até mesmo na documentação da Microsoft:
http://msdn.microsoft.com/en-us/library/hh873177(v=vs.110).aspx
Isso já não está certo. Qualquer método com
async
é assíncrono e então diz que deve retornar umTask
ouTask<T>
- o que não é certo para métodos no topo de uma pilha de chamadas, Button_Click por exemplo, ouasync void
.Claro, você deve considerar qual é o objetivo da convenção?
Você poderia dizer que a
Async
convenção de sufixo é para comunicar ao usuário da API que o método está aguardando. Para um método ser aguardado, ele deve retornarTask
para um void ouTask<T>
para um método de retorno de valor, o que significa que apenas o último pode ser sufixado comAsync
.Ou você pode dizer que a
Async
convenção de sufixo é para comunicar que o método pode retornar imediatamente, renunciando ao thread atual para realizar outro trabalho e potencialmente causando corridas.Esta citação de documento da Microsoft diz:
http://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_NamingConvention
O que nem mesmo menciona que seus próprios métodos assíncronos retornando
Task
precisam doAsync
sufixo, o que acho que todos concordamos que eles precisam.Portanto, a resposta a essa pergunta poderia ser: ambos. Em ambos os casos, você precisa anexar
Async
a métodos comasync
palavra - chave e que retornamTask
ouTask<T>
.Vou pedir a Stephen Toub que esclareça a situação.
Atualizar
Então eu fiz. E aqui está o que nosso bom homem escreveu:
A orientação sucinta da frase inicial de Stephen é bastante clara. Ele exclui
async void
porque é incomum querer criar uma API pública com esse design, pois a maneira correta de implementar um vazio assíncrono é retornar umaTask
instância simples e deixar o compilador fazer sua mágica. No entanto, se você quiser umpublic async void
,Async
é aconselhável anexar . Outrosasync void
métodos do topo da pilha , como manipuladores de eventos, geralmente não são públicos e não importam / qualificam.Para mim, isso me diz que, se eu me perguntar sobre como sufocar
Async
em umasync void
, provavelmente devo transformá-lo em umasync Task
para que os chamadores possam aguardar e, em seguida, anexarAsync
.fonte
PersonString
ouPriceDecimal
por que usarGetAsync
- os consumidores de APIs de APIs assíncronos não precisam se preocupar com isso, já que a solicitação sempre retorna após a conclusão de todas as tarefas. É bobo e realmente irritante para mim. Mas é apenas mais uma convenção que ninguém sabe realmente por que está lá.Eu construo muitos serviços de API e outros aplicativos que chamam outros sistemas onde a maior parte do meu código está rodando de forma assíncrona.
Minha própria regra prática que estou seguindo é:
Exemplos:
Apenas um método:
Mesmo método com duas assinaturas:
Isso faz sentido, pois são os mesmos dados que são retornados, mas a única coisa que difere é a maneira de retornar os dados , não os dados em si.
Eu também acho que essas convenções de nomenclatura existem devido à necessidade de introduzir métodos assíncronos e ainda manter a compatibilidade com versões anteriores.
Eu defendo que o novo código não deve usar o sufixo Async. É tão óbvio quanto o tipo de retorno de String ou Int, conforme mencionado anteriormente neste tópico.
fonte
O padrão assíncrono baseado em tarefas (TAP) determina que os métodos devem sempre retornar um
Task<T>
(ouTask
) e ser nomeados com um sufixo Async ; isso é separado do uso deasync
. AmbosTask<bool> Connect()
e serão compilados e executados perfeitamente, mas você não seguirá a convenção de nomenclatura TAP.async
Task<bool> Connect()
Se o corpo do método (independentemente do tipo de retorno ou nome) incluir
await
, você deve usarasync
; e o compilador dirá "O operador 'await' só pode ser usado dentro de um método assíncrono. ...". RetornarTask<T>
ouTask
não é "suficiente" para evitar o usoasync
. Consulte async (referência C #) para obter detalhes.Ambos e siga corretamente as convenções TAP. Você sempre pode usar a palavra - chave, mas obterá um aviso do compilador "Este método assíncrono não possui operadores 'await' e será executado de forma síncrona. ..." se o corpo não usar .
async
Task<bool> ConnectAsync()
Task<bool> ConnectAsync()
async
await
fonte
async
palavra - chave.async
- chave é a segunda parte da pergunta.async
modificador. Veja também exemplos de OPs,public async Task<bool> ConnectAsync()
(comasync
modificador) vspublic Task<bool> ConnectAsync()
(semasync
modificador). O próprio nome do método tem o sufixo "Async" em ambos os casos.Task
ou métodos que têmasync Task
.Este. A
async
palavra-chave não é o verdadeiro problema aqui. Se você implementar a assincronia sem usar aasync
palavra - chave, o método ainda será "Async", no sentido geral.fonte
Visto que
Task
eTask<T>
são tipos aguardáveis, eles representam algumas operações assíncronas. Ou pelo menos eles deveriam representar.Você deve adicionar sufixo
Async
a um método que, em alguns casos (não necessariamente todos), não retorna um valor, mas sim um invólucro em torno de uma operação em andamento. Esse wrapper geralmente é umTask
, mas no Windows RT pode serIAsyncInfo
. Siga sua intuição e lembre-se de que se um usuário de seu código vir aAsync
função, ele saberá que a invocação desse método está desacoplada do resultado desse método e que ele precisa agir de acordo.Observe que existem métodos como
Task.Delay
eTask.WhenAll
que retornamTask
e ainda não têm oAsync
sufixo.Observe também que existem
async void
métodos que representam disparar e esquecer o método assíncrono e é melhor você estar ciente de que o método é construído dessa forma.fonte
Eu diria que ele deve usar o sufixo Async se retornar uma Task, independentemente se o método é declarado com o
async
modificador ou não.A razão por trás disso é que o nome é declarado na interface. A interface declara o tipo de retorno que é a
Task
. Então, há duas implementações dessa interface, uma implementação a implementa usando oasync
modificador, a outra não.fonte
Na programação assíncrona com async e await (C #) , a Microsoft oferece a seguinte orientação:
Acho esta orientação incompleta e insatisfatória. Isso significa que, na ausência do
async
modificador, esse método deve ser nomeado emConnect
vez deConnectAsync
?Acho que não. Como indicado na resposta concisa por @Servy e quanto mais resposta detalhada por @Luke Puplett , eu acredito que é apropriado e, na verdade esperava que este método deve ser nomeado
ConnectAsync
(porque ele retorna um awaitable). Em mais apoio deste, @ John Skeet em esta resposta a outra pergunta anexaAsync
ao nome do método independentemente da presença doasync
modificador.Finalmente, em outra questão , considere este comentário de @Damien_The_Unbeliever :
A partir disso, deduzo que é a natureza assíncrona do método que determina como ele deve ser nomeado. O usuário do método nem saberá se o
async
modificador é usado em sua implementação (sem o código-fonte C # ou CIL).fonte