Em C #, quando você substitui um método, é permitido fazer a substituição assíncrona quando o método original não era. Parece uma forma ruim.
O exemplo que me trouxe a isso foi o seguinte: fui chamado para ajudar com um problema de teste de carga. Em cerca de 500 usuários simultâneos, o processo de login seria interrompido em um loop de redirecionamento. O IIS registrava exceções com a mensagem "Um módulo ou manipulador assíncrono concluído enquanto uma operação assíncrona ainda estava pendente". Algumas pesquisas me levaram a pensar que alguém estava abusando async void
, mas minhas pesquisas rápidas na fonte não encontraram nada.
Infelizmente, eu estava procurando por 'async \ svoid' (pesquisa regex) quando deveria estar procurando algo mais como 'async \ s [^ T]' (assumindo que a tarefa não estava totalmente qualificada ... você entendeu).
O que eu encontrei mais tarde foi async override void onActionExecuting(...
em um controlador base. Claramente, esse tinha que ser o problema, e era. Corrigir isso (tornando-o síncrono no momento) resolveu o problema.
Voltando à pergunta: Por que, oh, por que você pode marcar uma substituição como assíncrona quando o código de chamada nunca poderia aguardá-la?
Task
.Respostas:
A palavra - chave async permite que o método use a
await
sintaxe dentro de sua definição. Eu possoawait
em qualquer método que retorne umTask
tipo, independentemente de ser um método assíncrono.void
é um tipo de retorno legal (embora desanimado ) para um método assíncrono; por que não seria permitido? Do lado de fora,async
não está permitindo nada que você não possa fazer sem ele. O método com o qual você está tendo problemas poderia ter sido escrito para se comportar exatamente da mesma maneira sem ser assíncrono. Sua definição teria sido mais detalhada.Para os chamadores, um
async T
método é um método normal que os retornosT
(que se limita avoid
,Task
ouTask<A>
). O fato de ser um método assíncrono não faz parte da interface. Observe que o seguinte código é ilegal:Ele (ou código semelhante em uma classe abstrata) produz a seguinte mensagem de erro no VS2012:
Se eu fiz pretendem um método em uma classe de interface ou pai para ser tipicamente assíncrona, eu não posso usar
async
para se comunicar isso. Se eu quisesse implementá-lo com aawait
sintaxe, seria necessário ter métodos de substituição assíncrona (no caso da classe pai).fonte
override
nada, mas é disso que se trata.async
não muda a interface de um método, apenas o que é sintaticamente permitido em sua definição; portanto, se é uma substituição ou não, é completamente irrelevante.async
modificador pode ser aplicado apenas a implementações. Você não pode declarar um método assíncrono em uma interface, por exemplo, sublinhando que se um método é assíncrono ou não não faz parte da interface.O único objetivo da palavra-chave assíncrona é tornar a palavra-chave no corpo dessa função. Isso é necessário para que a adição da funcionalidade de espera não quebre o código existente. A Microsoft decidiu fazer uso de aguardar uma opção de aceitação. Para uma função que não está marcada como assíncrona, você pode definir uma variável chamada aguardar sem nenhum problema.
Portanto, async não faz parte da assinatura de uma função e não tem significado semântico no código IL gerado. Está estritamente presente para o compilador saber como compilar corretamente a função. Ele também instrui o compilador a garantir que apenas Tarefa, Tarefa <T> ou nula esteja sendo retornada.
fonte