Pelo que entendi, uma das principais coisas que async
e oawait
que fazemos é tornar o código fácil de escrever e ler - mas usá-los é o mesmo que gerar threads de plano de fundo para executar lógica de longa duração?
Atualmente, estou experimentando o exemplo mais básico. Adicionei alguns comentários em linha. Você pode esclarecer isso para mim?
// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
{
Task<int> access = DoSomethingAsync();
// task independent stuff here
// this line is reached after the 5 seconds sleep from
// DoSomethingAsync() method. Shouldn't it be reached immediately?
int a = 1;
// from my understanding the waiting should be done here.
int x = await access;
}
async Task<int> DoSomethingAsync()
{
// is this executed on a background thread?
System.Threading.Thread.Sleep(5000);
return 1;
}
c#
.net
asynchronous
async-await
Dan Dinu
fonte
fonte
Respostas:
Ao usar
async
eawait
o compilador gera uma máquina de estado em segundo plano.Aqui está um exemplo no qual espero poder explicar alguns dos detalhes de alto nível que estão acontecendo:
OK, então o que acontece aqui:
Task<int> longRunningTask = LongRunningOperationAsync();
começa a executarLongRunningOperation
Trabalho independente é feito, vamos assumir que o Thread Principal (Thread ID = 1)
await longRunningTask
seja alcançado.Agora, se o
longRunningTask
não tiver terminado e ainda estiver em execução,MyMethodAsync()
retornará ao seu método de chamada, assim o thread principal não será bloqueado. Quando issolongRunningTask
for feito, um encadeamento do ThreadPool (pode ser qualquer encadeamento) retornará aoMyMethodAsync()
seu contexto anterior e continuará a execução (nesse caso, imprimindo o resultado no console).Um segundo caso seria que
longRunningTask
ele já terminou sua execução e o resultado está disponível. Ao chegar aoawait longRunningTask
já temos o resultado, o código continuará sendo executado no mesmo encadeamento. (neste caso, resultado da impressão no console). Claro que este não é o caso do exemplo acima, onde há umTask.Delay(1000)
envolvido.fonte
Eles devem tornar o código assíncrono fácil de escrever e ler, sim.
De modo nenhum.
A
async
palavra-chave ativa aawait
palavra - chave. Portanto, qualquer método usandoawait
deve ser marcadoasync
.Não, porque os
async
métodos não são executados em outro encadeamento por padrão.Não.
Você pode achar minha
async
/await
introdução útil. Os documentos oficiais do MSDN também são extraordinariamente bons (principalmente a seção TAP ), e aasync
equipe publicou uma excelente FAQ .fonte
async
métodos não são executados em outro encadeamento por padrão. No seu exemplo, aSleep()
chamada dentroDoSomethingAsync()
bloqueia o encadeamento atual que impede a execução de continuar dentrobutton1_Click()
até aDoSomethingAsync()
conclusão. Note-se que, enquantoThread.Sleep()
bloqueia a thread em execução,Task.Delay() does not.
Explicação
Aqui está um exemplo rápido de
async
/await
em um nível alto. Há muito mais detalhes a serem considerados além disso.Nota:
Task.Delay(1000)
simula o trabalho por 1 segundo. Eu acho que é melhor pensar nisso como aguardar uma resposta de um recurso externo. Como nosso código está aguardando uma resposta, o sistema pode definir a tarefa em execução para o lado e retornar a ela assim que terminar. Enquanto isso, ele pode fazer algum outro trabalho nesse segmento.No exemplo abaixo, o primeiro bloco está fazendo exatamente isso. Inicia todas as tarefas imediatamente (as
Task.Delay
linhas) e as coloca para o lado. O código será pausado naawait a
linha até que o atraso de 1 segundo seja concluído antes de passar para a próxima linha. Desdeb
,c
,d
, ee
tudo começou a ser executado em quase exatamente o mesmo tempo quea
(devido à falta do await), que deve terminar em aproximadamente o mesmo tempo neste caso.No exemplo abaixo, o segundo bloco está iniciando uma tarefa e aguardando a conclusão (é isso que
await
ocorre) antes de iniciar as tarefas subseqüentes. Cada iteração disso leva 1 segundo. oawait
está pausando o programa e aguardando o resultado antes de continuar. Essa é a principal diferença entre o primeiro e o segundo bloco.Exemplo
RESULTADO:
Informações adicionais sobre o SynchronizationContext
Nota: É aqui que as coisas ficam um pouco nebulosas para mim; portanto, se eu estiver errado em algo, corrija-me e atualizarei a resposta. É importante ter um entendimento básico de como isso funciona, mas você pode sobreviver sem ser um especialista, desde que nunca use
ConfigureAwait(false)
, embora você provavelmente perca alguma oportunidade de otimização, presumo.Há um aspecto disso que torna o conceito
async
/await
um pouco mais difícil de entender. É o fato de que, neste exemplo, tudo isso está acontecendo no mesmo encadeamento (ou pelo menos o que parece ser o mesmo encadeamento em relação ao seuSynchronizationContext
). Por padrão, oawait
restaurará o contexto de sincronização do encadeamento original em que estava sendo executado. Por exemplo, no ASP.NET você tem umHttpContext
que está vinculado a um encadeamento quando uma solicitação é recebida. Esse contexto contém itens específicos da solicitação Http original, como o objeto Request original, que possui linguagem, endereço IP, cabeçalhos etc. Se você alternar os threads no meio do processamento de algo, poderá acabar tentando extrair informações desse objeto em um objeto diferente.HttpContext
o que pode ser desastroso. Se você sabe que não usará o contexto para nada, pode optar por "não se importar" com isso. Isso basicamente permite que seu código seja executado em um thread separado sem trazer o contexto com ele.Como você consegue isso? Por padrão, o
await a;
código está realmente assumindo que você deseja capturar e restaurar o contexto:Se você deseja permitir que o código principal continue em um novo encadeamento sem o contexto original, basta usar false em vez de true para que ele saiba que não precisa restaurar o contexto.
Após a pausa do programa, ele continuará potencialmente em um encadeamento totalmente diferente com um contexto diferente. É daí que surgiria a melhoria de desempenho - ela poderia continuar em qualquer encadeamento disponível sem precisar restaurar o contexto original com o qual começou.
Isso é confuso? Isso aí! Você pode descobrir isso? Provavelmente! Depois de entender os conceitos, passe para as explicações de Stephen Cleary, que tendem a ser mais voltadas para alguém com um conhecimento técnico de
async
/await
já.fonte
await MethodCall()
é um desperdício absoluto? Você também pode soltar oawait
/async
?await
, acho que ele libera o thread de volta para a piscina em vez de segurá-lo. Isso o torna disponível para uso em outros lugares enquanto aguarda o retorno da tarefaAlém das outras respostas, dê uma olhada em aguardar (Referência de C #)
e, mais especificamente, no exemplo incluído, explica um pouco a sua situação
fonte
Task.Delay
disparos.Mostrando as explicações acima em ação em um simples programa de console:
E a saída é:
Portanto,
TestAsyncAwaitMethods
. Isso retorna imediatamente sem interromper o encadeamento atual e imediatamente vemos a mensagem 'Pressione qualquer tecla para sair'LongRunningMethod
está sendo executado em segundo plano. Uma vez concluído, outro segmento do Threadpool pega esse contexto e exibe a mensagem finalPortanto, nenhum segmento está bloqueado.
fonte
return 1
parte merece mais explicações: aawait
palavra - chave permite retornar o tipo subjacenteTask<T>
diretamente, facilitando assim a adaptação do código existente ao mundo aguardar / assíncrono . Mas você não precisa retornar um valor, pois é possível retornar aTask
sem especificar um tipo de retorno, o que seria equivalente a umvoid
método síncrono . Lembre-se de que o C # permiteasync void
métodos, mas evite fazê-lo, a menos que esteja lidando com manipuladores de eventos.Eu acho que você escolheu um mau exemplo com
System.Threading.Thread.Sleep
O
async
objetivo de uma tarefa é permitir que ela seja executada em segundo plano sem bloquear o encadeamento principal, como executar umDownloadFileAsync
System.Threading.Thread.Sleep
não é algo que está "sendo feito", apenas dorme e, portanto, sua próxima linha é alcançada após 5 segundos ...Leia este artigo, acho que é uma ótima explicação
async
eawait
conceito: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspxfonte
Thread.Sleep
bloqueia o thread (o thread não pode fazer mais nada além de ficar ocioso), mas um método assíncrono não. No caso deDownloadFileAsync
, o encadeamento pode fazer outra coisa até que uma resposta seja enviada do servidor remoto. Um espaço reservado melhor para "alguma tarefa que leva tempo" em um método assíncrono éTask.Delay
, pois ele é realmente assíncrono.async
palavra - chave. Mas seu método ainda era executado de forma síncrona, e essa resposta explicava perfeitamente o porquê: porque ele não executou nenhum código assíncrono. Os métodos marcadosasync
ainda são executados de forma síncrona até você ficarawait
incompletoTask
. Se não houverawait
, o método será executado de forma síncrona e o compilador avisará sobre isso.Aqui está um rápido programa de console para deixar claro para quem segue. O
TaskToDo
método é o seu método de execução longa que você deseja fazer assíncrono. A execução assíncrona é feita peloTestAsync
método O método de loops de teste apenas executa asTaskToDo
tarefas e as executa de forma assíncrona. Você pode ver isso nos resultados porque eles não são concluídos na mesma ordem de execução para execução - eles estão relatando o thread da interface do usuário do console quando concluídos. Simplista, mas acho que os exemplos simplistas destacam o núcleo do padrão melhor do que os exemplos mais envolvidos:fonte
Para um aprendizado mais rápido ..
Entenda o fluxo de execução do método (com um diagrama): 3 minutos
Introspecção de perguntas (pelo aprendizado): 1 min
Obtenha rapidamente o açúcar da sintaxe: 5 minutos
Compartilhe a confusão de um desenvolvedor: 5 minutos
Problema: Altere rapidamente uma implementação do código normal do mundo real para código assíncrono: 2 minutos
Onde a próxima?
Entenda o fluxo de execução do método (com um diagrama): 3 minutos
Nesta imagem, concentre-se no número 6 (nada mais)
Na etapa 6: a execução parou aqui, pois ficou sem trabalho. Para continuar, ele precisa de um resultado de getStringTask (tipo de função). Portanto, ele usa um
await
operador para suspender seu progresso e devolver o controle (rendimento) ao chamador (deste método em que estamos). A chamada real para getStringTask foi feita anteriormente no # 2. No segundo, foi feita uma promessa de retornar um resultado de sequência. Mas quando retornará o resultado? Devemos (# 1: AccessTheWebAsync) fazer uma segunda chamada novamente? Quem obtém o resultado, # 2 (declaração de chamada) ou # 6 (declaração de espera)O chamador externo do AccessTheWebAsync () também está aguardando agora. Portanto, quem está chamando aguardando AccessTheWebAsync e AccessTheWebAsync está esperando GetStringAsync no momento. O interessante é que o AccessTheWebAsync fez algum trabalho antes de esperar (nº 4), talvez para economizar tempo. A mesma liberdade de multitarefa também está disponível para o chamador externo (e todos os chamadores na cadeia) e essa é a maior vantagem desse coisinho 'assíncrono'! Você sente que é síncrono ... ou normal, mas não é.
Lembre-se de que o método já foi retornado (nº 2), não pode retornar novamente (sem segunda vez). Então, como o chamador saberá? É tudo sobre tarefas! Tarefa foi aprovada. A tarefa foi aguardada (não método, não valor). O valor será definido na tarefa. O status da tarefa será definido como concluído. O chamador apenas monitora a tarefa (nº 6). Então 6 # é a resposta para onde / quem obtém o resultado. Mais leituras para mais tarde aqui .
Introspecção de perguntas para fins de aprendizado: 1 min
Vamos ajustar um pouco a pergunta:
Como o aprendizado
Task
abrange automaticamente os outros dois (e responde à sua pergunta)Obtenha rapidamente o açúcar da sintaxe: 5 minutos
Antes da conversão (método original)
internal static int Method(int arg0, int arg1) { int result = arg0 + arg1; IO(); // Do some long running IO. return result; }
um método Task-ified para chamar o método acima
internal static Task<int> MethodTask(int arg0, int arg1) { Task<int> task = new Task<int>(() => Method(arg0, arg1)); task.Start(); // Hot task (started task) should always be returned. return task; }
Nós mencionamos aguardar ou assíncrono? Não. Chame o método acima e você terá uma tarefa que poderá monitorar. Você já sabe o que a tarefa retorna .. um número inteiro.
Chamar uma tarefa é um pouco complicado e é quando as palavras-chave começam a aparecer. Vamos chamar MethodTask ()
internal static async Task<int> MethodAsync(int arg0, int arg1) { int result = await HelperMethods.MethodTask(arg0, arg1); return result; }
O mesmo código acima foi adicionado à imagem abaixo:
await
async
(sintaxe obrigatória)Async
como prefixo (padrão de codificação)await
é fácil de entender, mas os dois restantes (async
,Async
) podem não ser :). Bem, ele deve fazer muito mais sentido para o compilador though.Further lê para mais tarde aquiCompartilhe a confusão de um desenvolvedor: 5 minutos
Um desenvolvedor cometeu um erro ao não implementar,
Task
mas ainda funciona! Tente entender a pergunta e apenas a resposta aceita fornecida aqui . Espero que você tenha lido e compreendido completamente. O resumo é que podemos não ver / implementar a 'Tarefa', mas ela é implementada em algum lugar da classe pai. Da mesma forma, em nosso exemplo, chamar um já construídoMethodAsync()
é muito mais fácil do que implementar esse método com umTask
(MethodTask()
). Muitos desenvolvedores acham difícil entender o processo deTasks
conversão de um código para assíncrono.Dica: Tente encontrar uma implementação Async existente (como
MethodAsync
ouToListAsync
) para terceirizar a dificuldade. Portanto, precisamos lidar apenas com o Async e aguardar (o que é fácil e bastante semelhante ao código normal)Problema: Altere rapidamente uma implementação do código normal do mundo real para operação assíncrona: 2 minutos
A linha de código mostrada abaixo na Camada de Dados começou a quebrar (muitos lugares). Porque atualizamos alguns dos nossos códigos do .Net framework 4.2. * Para o .Net core. Tivemos que corrigir isso em 1 hora em todo o aplicativo!
mole-mole!
Async
e simplesawait
.linha de código de chamada mudou assim
A assinatura do método foi alterada de
Contract GetContract(int contractnumber)
para
async Task<Contract> GetContractAsync(int contractnumber)
O método de chamada também foi afetado:
GetContractAsync(123456);
foi chamado comoGetContractAsync(123456).Result;
Nós mudamos em todos os lugares em 30 minutos!
Mas o arquiteto nos disse para não usar a biblioteca EntityFramework apenas para isso! oops! drama! Em seguida, fizemos uma implementação de tarefa personalizada (yuk). Que você sabe como. Ainda é fácil! ..ainda yuk ..
Onde a próxima? Há um vídeo rápido maravilhoso que poderíamos assistir sobre a conversão de chamadas síncronas em assíncronas no ASP.Net Core , talvez essa seja provavelmente a direção que se seguiria depois de ler isso.
fonte
Todas as respostas aqui usam
Task.Delay()
ou alguma outraasync
função incorporada. Mas aqui está o meu exemplo que não usa nenhuma dessasasync
funções:fonte
task.Wait();
e como ele pode ser usado para evitar assíncrono / aguardar o inferno: PEsta resposta visa fornecer algumas informações específicas para o ASP.NET.
Ao utilizar async / waitit no controlador MVC, é possível aumentar a utilização do conjunto de encadeamentos e obter uma taxa de transferência muito melhor, conforme explicado no artigo abaixo,
http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4
fonte
Assinatura e Aguardar Explicação Simples
Analogia Simples
Uma pessoa pode esperar pelo trem da manhã. Isso é tudo o que eles estão fazendo, pois essa é a principal tarefa que eles estão executando no momento. (programação síncrona (o que você normalmente faz!))
Outra pessoa pode esperar o trem da manhã enquanto fuma um cigarro e depois toma seu café. (Programação assíncrona)
O que é programação assíncrona?
A programação assíncrona é onde um programador escolhe executar parte de seu código em um thread separado do thread principal de execução e depois notifica o thread principal quando terminar.
O que a palavra-chave assíncrona realmente faz?
Prefixando a palavra-chave assíncrona para um nome de método como
permite que o programador use a palavra-chave wait ao chamar tarefas assíncronas. É tudo o que faz.
Por que isso é importante?
Em muitos sistemas de software, o encadeamento principal é reservado para operações relacionadas especificamente à interface do usuário. Se eu estiver executando um algoritmo recursivo muito complexo que leva 5 segundos para ser concluído no meu computador, mas estou executando isso no Thread Principal (thread da UI) Quando o usuário tentar clicar em qualquer coisa no meu aplicativo, ele parecerá congelado como meu thread principal está na fila e atualmente está processando muitas operações. Como resultado, o thread principal não pode processar o clique do mouse para executar o método a partir do botão.
Quando você usa Async e Await?
Use as palavras-chave assíncronas idealmente quando estiver fazendo algo que não envolva a interface do usuário.
Digamos que você esteja escrevendo um programa que permita ao usuário desenhar no celular, mas a cada 5 segundos ele verificará o tempo na internet.
Deveríamos aguardar a ligação que a pesquisa faz a cada 5 segundos para a rede para obter o clima, já que o usuário do aplicativo precisa continuar interagindo com a tela de toque do celular para tirar fotos bonitas.
Como você usa Async e Await
Seguindo o exemplo acima, aqui está um pseudo-código de como escrevê-lo:
Notas adicionais - Atualização
Esqueci de mencionar em minhas anotações originais que, em C #, você só pode aguardar métodos agrupados em tarefas. por exemplo, você pode aguardar este método:
Você não pode aguardar métodos que não são tarefas como esta:
Sinta-se livre para revisar o código fonte da classe Task aqui .
fonte
Async / Await
Na verdade Async / Await são um par de palavras-chave que são apenas açúcar sintático para criar um retorno de chamada de uma tarefa assíncrona.
Tome como exemplo esta operação:
O código acima tem várias desvantagens. Os erros não são transmitidos e é difícil de ler. Mas Async e Await entram para nos ajudar:
As chamadas em espera devem estar nos métodos Async. Isso tem algumas vantagens:
NOTA : Async e Await são usados com chamadas assíncronas para não fazer isso. Você precisa usar o Task Libary para isso, como Task.Run ().
Aqui está uma comparação entre aguardar e nenhum aguardar soluções
Esta é a solução none assíncrona:
Este é o método assíncrono:
Você pode realmente chamar um método assíncrono sem a palavra-chave wait, mas isso significa que qualquer exceção aqui é engolida no modo de liberação:
Async e Await não se destinam à computação paralela. Eles são usados para não bloquear seu segmento principal. Quando se trata de aplicativos asp.net ou Windows, o bloqueio do thread principal devido a uma chamada de rede é uma coisa ruim. Se você fizer isso, seu aplicativo ficará sem resposta ou até travará.
Confira ms docs para mais exemplos.
fonte
Para ser sincero, ainda acho que a melhor explicação é sobre futuro e promessas na Wikipedia: http://en.wikipedia.org/wiki/Futures_and_promises
A idéia básica é que você tenha um conjunto separado de encadeamentos que executam tarefas de forma assíncrona. Ao usá-lo. O objeto, no entanto, promete que executará a operação em algum momento e fornecerá o resultado quando solicitado. Isso significa que ele será bloqueado quando você solicitar o resultado e ainda não tiver concluído, mas, caso contrário, será executado no pool de threads.
A partir daí, você pode otimizar as coisas: algumas operações podem ser implementadas de forma assíncrona e você pode otimizar coisas como E / S de arquivos e comunicação de rede, agrupando solicitações subsequentes e / ou reordenando-as. Não tenho certeza se isso já está na estrutura de tarefas da Microsoft - mas se não for, isso seria uma das primeiras coisas que eu acrescentaria.
Você pode realmente implementar o padrão futuro com rendimentos no C # 4.0. Se você quiser saber exatamente como funciona, recomendo este link que faz um trabalho decente: http://code.google.com/p/fracture/source/browse/trunk/Squared/TaskLib/ . No entanto, se você começar a brincar com ele, perceberá que realmente precisa de suporte ao idioma se quiser fazer todas as coisas legais - exatamente o que a Microsoft fez.
fonte
Veja este violão https://dotnetfiddle.net/VhZdLU (e melhore-o, se possível) para executar um aplicativo de console simples que mostre os usos de Task, Task.WaitAll (), assíncrono e aguarde operadores no mesmo programa.
Esse violino deve limpar seu conceito de ciclo de execução.
Aqui está o código de exemplo
Rastreio vindo da janela Saída:
fonte
fonte
Em um nível superior:
1) A palavra-chave assíncrona permite aguardar e é tudo o que faz. A palavra-chave assíncrona não executa o método em um thread separado. O método f async inicial é executado de forma síncrona até que seja aguardado em uma tarefa demorada.
2) Você pode aguardar um método que retorne Tarefa ou Tarefa do tipo T. Você não pode aguardar no método nulo assíncrono.
3) No momento em que os encontros do thread principal aguardam tarefas demoradas ou quando o trabalho real é iniciado, o thread principal retorna ao chamador do método atual.
4) Se o thread principal aguarda uma tarefa que ainda está em execução, ele não espera por isso e retorna ao chamador do método atual. Dessa maneira, o aplicativo permanece responsivo.
5) Aguardar tarefa de processamento, agora será executado em um encadeamento separado do conjunto de encadeamentos.
6) Quando esta tarefa aguardada for concluída, todo o código abaixo será executado pelo thread separado
Abaixo está o código de exemplo. Execute-o e verifique o ID do encadeamento
fonte
A maneira que eu entendo que é também, deve haver um terceiro mandato adicionado à mistura:
Task
.Async
é apenas um qualificador que você coloca no seu método para dizer que é um método assíncrono.Task
é o retorno daasync
função. Ele é executado de forma assíncrona.Você é
await
uma tarefa. Quando a execução do código atinge essa linha, o controle retorna ao chamador da sua função original circundante.Se, em vez disso, você atribuir o retorno de uma
async
função (ou sejaTask
) a uma variável, quando a execução do código atingir essa linha, ela continuará além dessa linha na função circundante enquanto aTask
execução é assincrona.fonte
Este artigo MDSN: Programação assíncrona com assíncrono e espera (C #) explica explicitamente:
fonte
No código a seguir, o método HttpClient GetByteArrayAsync retorna uma tarefa, getContentsTask. A tarefa é uma promessa de produzir a matriz de bytes real quando a tarefa estiver concluída. O operador wait é aplicado a getContentsTask para suspender a execução em SumPageSizesAsync até que getContentsTask seja concluído. Enquanto isso, o controle é retornado ao chamador de SumPageSizesAsync. Quando getContentsTask é concluído, a expressão de espera é avaliada como uma matriz de bytes.
fonte
Abaixo está o código que lê o arquivo do Excel abrindo a caixa de diálogo e, em seguida, usa async e aguarde para executar de forma assíncrona o código que lê uma por uma linha do Excel e liga à grade
fonte
As respostas aqui são úteis como orientação geral sobre aguardar / assíncrono. Eles também contêm alguns detalhes sobre como aguardar / assíncrono é conectado. Gostaria de compartilhar com você uma experiência prática que você deve saber antes de usar esse padrão de design.
O termo "aguardar" é literal, portanto, qualquer que seja o segmento em que você o chame, aguardará o resultado do método antes de continuar. No segmento de primeiro plano , isso é um desastre . O encadeamento em primeiro plano carrega o ônus de construir seu aplicativo, incluindo visualizações, modelos de visualização, animações iniciais e tudo o mais que você tiver usado com esses elementos. Então, quando você aguarda o segmento de primeiro plano, para o aplicativo. O usuário espera e espera quando nada parece acontecer. Isso fornece uma experiência negativa ao usuário.
Certamente, você pode aguardar um encadeamento em segundo plano usando vários meios:
O código completo para essas observações está em https://github.com/marcusts/xamarin-forms-annoyances . Veja a solução chamada AwaitAsyncAntipattern.sln.
O site do GitHub também fornece links para uma discussão mais detalhada sobre este tópico.
fonte
async / await
é o açúcar sintático para retornos de chamada, não tem nada a ver com a segmentação. msdn.microsoft.com/en-us/magazine/hh456401.aspx É para código não vinculado à CPU, por exemplo, aguardando entrada ou atraso.Task.Run
deve ser usado apenas para código vinculado à CPU blog.stephencleary.com/2013/10/…The term "await" is literal, so whatever thread you call it on will wait for the result of the method before continuing.
Isso não é verdade - talvez você quis dizer Task.Wait ()? Quando você usaawait
, ele define o restante do método como uma continuação a ser executada quando o que você espera for concluído. Ele sai do método em que você o usou, para que o chamador possa continuar. Então, quando a linha aguardada estiver realmente concluída, ele concluirá o restante desse método em algum encadeamento (geralmente um encadeamento de trabalho).async/await
é sobre liberar .NET Threads. Quandoawait
uma operação verdadeiramente assíncrona (como o File.WriteAsync do .NET), ela suspende o restante do método usadoawait
, para que o chamador possa continuar e potencialmente concluir sua finalidade. Não há nenhum bloqueio de thread ou aguardando aawait
operação -ed. Quando a operação que vocêawait
edita é concluída, o restante doasync/await
método é colocado em um encadeamento e executado (semelhante a uma idéia de retorno de chamada).