Os métodos de ação assíncrona são úteis quando uma ação deve executar várias operações independentes de execução longa.
Um uso típico para a classe AsyncController são as chamadas de serviço da Web de longa duração.
As chamadas do meu banco de dados devem ser assíncronas?
O pool de threads do IIS geralmente pode lidar com muito mais solicitações de bloqueio simultâneo do que um servidor de banco de dados. Se o banco de dados for o gargalo, as chamadas assíncronas não irão acelerar a resposta do banco de dados. Sem um mecanismo de limitação, o envio eficiente de mais trabalho para um servidor de banco de dados sobrecarregado usando chamadas assíncronas apenas transfere mais carga para o banco de dados. Se o seu banco de dados for o gargalo, as chamadas assíncronas não serão a bala mágica.
Você deve dar uma olhada nas referências 1 e 2
Derivado de @PanagiotisKanavos comentários:
Além disso, assíncrono não significa paralelo. A execução assíncrona libera um thread valioso do conjunto de encadeamentos do bloqueio de um recurso externo, sem custo de complexidade ou desempenho. Isso significa que a mesma máquina IIS pode lidar com solicitações mais simultâneas, não que seja executada mais rapidamente.
Você também deve considerar que as chamadas de bloqueio começam com um spinwait com uso intenso da CPU. Durante os períodos de estresse, o bloqueio de chamadas resultará em atrasos crescentes e na reciclagem do pool de aplicativos. Chamadas assíncronas simplesmente evitam isso
Você pode encontrar meu artigo do MSDN sobre o assunto útil ; Ocupei muito espaço nesse artigo, descrevendo quando você deveria usar
async
no ASP.NET, não apenas como usáasync
-lo.Primeiro, entenda que
async
/await
é sobre liberar threads . Nos aplicativos da GUI, trata-se principalmente de liberar o encadeamento da GUI para que a experiência do usuário seja melhor. Nos aplicativos de servidor (incluindo o ASP.NET MVC), trata-se principalmente de liberar o encadeamento de solicitação para que o servidor possa ser dimensionado.Em particular, não irá:
await
.await
somente "produz" para o pool de threads do ASP.NET, não para o navegador.Eu diria que é bom usá-lo em qualquer lugar em que você esteja fazendo E / S. Porém, pode não ser necessariamente benéfico (veja abaixo).
No entanto, é ruim usá-lo para métodos ligados à CPU. Às vezes, os desenvolvedores acham que podem obter os benefícios
async
apenas chamandoTask.Run
seus controladores, e essa é uma ideia horrível. Como esse código acaba liberando o encadeamento de solicitação, retomando outro encadeamento, não há benefício algum (e, de fato, eles estão tendo a penalidade de alternar os encadeamentos extras)!Você pode usar qualquer método que esteja disponível. No momento, a maioria dos principais players suporta
async
, mas há alguns que não. Se o seu ORM não suportarasync
, não tente envolvê-loTask.Run
ou algo assim (veja acima).Note que eu disse "você poderia usar". Se você está falando sobre o ASP.NET MVC com um único back-end de banco de dados, você (quase certamente) não obterá nenhum benefício de escalabilidade
async
. Isso ocorre porque o IIS pode manipular solicitações muito mais simultâneas do que uma única instância do SQL server (ou outro RDBMS clássico). No entanto, se o seu back-end é mais moderno - um cluster de servidor SQL, SQL Azure, NoSQL, etc - e seu backend pode escalar, e o gargalo escalabilidade é IIS, em seguida, você pode obter um benefício escalabilidade deasync
.Quantas você quiser. No entanto, observe que muitos ORMs têm uma regra de uma operação por conexão. Em particular, o EF permite apenas uma única operação por DbContext; isso é verdade se a operação é síncrona ou assíncrona.
Além disso, lembre-se da escalabilidade do seu back-end novamente. Se você está acessando uma única instância do SQL Server e seu IIS já é capaz de manter o SQLServer em sua capacidade total, dobrar ou triplicar a pressão no SQLServer não ajudará em nada.
fonte
Como de costume na programação, isso depende . Sempre há uma troca ao seguir um determinado caminho.
async-await
brilha em lugares em que você sabe que receberá solicitações simultâneas ao seu serviço e deseja expandir com facilidade . Comoasync-await
ajuda na expansão? No fato de que quando você invoca uma chamada de E / S assíncrona de forma síncrona , como uma chamada de rede ou atinge seu banco de dados, o encadeamento atual responsável pela execução é bloqueado, aguardando a conclusão da solicitação. Ao usarasync-await
, você habilita a estrutura para criar uma máquina de estado para você, garantindo que, após a conclusão da chamada de E / S, seu método continue sendo executado a partir de onde parou.Um ponto a ser observado é que essa máquina de estado possui uma sobrecarga sutil. Tornar um método assíncrono não o executa mais rapidamente , e esse é um fator importante para entender e um conceito errôneo que muitas pessoas têm.
Outra coisa a ser levada em consideração ao usar
async-await
é o fato de ser assíncrono o tempo todo , o que significa que você verá o assíncrono penetrar em toda a pilha de chamadas, do topo ao topo. Isso significa que, se você deseja expor APIs síncronas, geralmente se encontra duplicando uma certa quantidade de código, pois async e sync não se misturam muito bem.Se você optar por seguir o caminho do uso de chamadas de E / S assíncronas,
async-await
será uma boa opção, pois mais e mais fornecedores modernos de banco de dados expõem o método assíncrono implementando o TAP (Task Asynchronous Pattern).Quantas você desejar, desde que siga as regras declaradas pelo seu provedor de banco de dados. Não há limite para a quantidade de chamadas assíncronas que você pode fazer. Se você tiver consultas independentes umas das outras e puderem ser feitas simultaneamente, poderá girar uma nova tarefa para cada uma delas e
await Task.WhenAll
aguardar a conclusão de ambas.fonte
scale out well
pode significaryour server won't die under load
. Ou pode ser um caso deonce burned ...
Meus 5 centavos:
async/await
se e somente se você fizer uma operação de E / S, como banco de dados ou serviço da web de serviço externo.PS Existem casos excepcionais para o ponto 1, mas você precisa ter um bom entendimento de componentes internos assíncronos para isso.
Como uma vantagem adicional, você pode fazer algumas chamadas de E / S em paralelo, se necessário:
fonte
async
as ações ajudam melhor quando as ações executam algumas operações de E / S no banco de dados ou em algumas chamadas vinculadas à rede, nas quais o encadeamento que processa a solicitação será interrompido antes de obter resposta da chamada vinculada ao DB ou à rede que você acabou de invocar. É melhor você aguardar com eles e isso realmente melhorará a capacidade de resposta do seu aplicativo (porque menos threads de entrada \ saída ASP ficarão paralisados enquanto aguarda o banco de dados ou qualquer outra operação como essa). Em todas as minhas aplicações, sempre que muitas chamadas para o banco de dados são muito necessárias, eu sempre as envolvi no método esperado e chamei isso deawait
palavra - chave.fonte
Como você sabe, o MVC suporta controladores assíncronos e você deve tirar proveito disso. Caso o seu Controller execute uma operação longa (pode ser uma E / S baseada em disco ou uma chamada de rede para outro serviço remoto), se a solicitação for tratada de maneira síncrona, o encadeamento do IIS ficará ocupado o tempo todo. Como resultado, o encadeamento está apenas aguardando a conclusão da operação demorada. Pode ser melhor utilizado atendendo a outras solicitações enquanto a operação solicitada primeiro estiver em andamento. Isso ajudará a atender solicitações mais simultâneas. Seu serviço da web será altamente escalável e não será facilmente encontrado no problema do C10k . É uma boa idéia usar async / waitit para consultas de banco de dados. e sim, você pode usá-los quantas vezes quiser.
Dê uma olhada aqui para obter excelentes conselhos.
fonte
Minha experiência é que hoje muitos desenvolvedores usam
async/await
como padrão os controladores.Minha sugestão seria: use-o somente quando souber que o ajudará .
O motivo é que, como Stephen Cleary e outros já mencionaram, ele pode apresentar problemas de desempenho, em vez de resolvê-los, e ajudará você apenas em um cenário específico:
fonte
É bom fazer isso onde quer que você possa usar um método assíncrono, especialmente quando tiver problemas de desempenho no nível do processo do operador, o que acontece com operações massivas de dados e cálculos. Caso contrário, não há necessidade, porque o teste de unidade precisará de fundição.
Sim, é melhor usar async para qualquer operação de banco de dados possível para evitar problemas de desempenho no nível dos processos do trabalhador. Observe que o EF criou muitas alternativas assíncronas para a maioria das operações, como:
O céu é o limite
fonte