Recentemente, eu estava lendo algum código que usa muitos métodos assíncronos, mas às vezes precisa executá-los de forma síncrona. O código faz:
Foo foo = GetFooAsync(...).GetAwaiter().GetResult();
É o mesmo que
Foo foo = GetFooAsync(...).Result;
c#
async-await
Jay Bazuzi
fonte
fonte
GetResult
: "Este tipo e seus membros devem ser usados pelo compilador." Outra pessoa não deveria estar usando.async
/await
método em MVC, por exemplo)Respostas:
Bastante. Porém, uma pequena diferença: se
Task
falhar,GetResult()
lançará apenas a exceção causada diretamente, enquantoTask.Result
lançará umAggregateException
. No entanto, qual é o sentido de usar um desses quando éasync
? A opção 100x melhor é usarawait
.Além disso, você não deve usar
GetResult()
. É para ser apenas para uso do compilador, não para você. Mas se você não quer o irritanteAggregateException
, use-o.fonte
async Task
testes de unidade, e já há algum tempo.The 100x better option is to use await.
Eu odeio declarações como esta, se eu pudesse dar um tapaawait
na frente dela, eu faria. Mas, quando eu estou tentando obter o código assíncrono para trabalhar contra código não-async como o que muitas vezes acontece-me muito em Xamarin, eu acabar tendo que usar coisas comoContinueWith
um monte, a fim de torná-lo não impasse a interface do usuário. Edit: Eu sei que isso é antigo, mas isso não alivia minha frustração ao encontrar respostas que afirmam isso sem alternativas para situações em que você não pode simplesmente usarawait
.Task.GetAwaiter().GetResult()
é preferidoTask.Wait
eTask.Result
porque propaga exceções em vez de agrupá-las em um arquivoAggregateException
. No entanto, todos os três métodos causam o potencial de problemas de falta de deadlock e pool de encadeamentos. Todos eles devem ser evitados em favor deasync/await
.A citação abaixo explica por que
Task.Wait
eTask.Result
não contém simplesmente o comportamento de propagação de exceção deTask.GetAwaiter().GetResult()
(devido a uma "barra de compatibilidade muito alta").https://blogs.msdn.microsoft.com/pfxteam/2011/09/28/task-exception-handling-in-net-4-5/
http://blog.stephencleary.com/2014/12/a-tour-of-task-part-6-results.html
fonte
Task.GetAwaiter().GetResult()
é equivalente aawait task
. Presumo que a primeira opção seja usada quando o método não puder ser marcado comasync
(construtor por exemplo). Isso está correto? Se sim, então ele colide com a resposta top @ It'sNotALieTask.GetAwaiter().GetResult()
é equivalente a maisTask.Wait
eTask.Result
(em que todos os três vai bloquear de forma síncrona e têm o potencial para impasses), masTask.GetAwaiter().GetResult()
tem o comportamento de propagação excepção de tarefa esperam.https://github.com/aspnet/Security/issues/59
fonte
Task.WhenAll(task1, task2).GetAwaiter().GetResult();
.Outra diferença é quando a
async
função retorna apenas emTask
vez deTask<T>
então você não pode usarEnquanto que
ainda funciona.
Eu sei que o código de exemplo na pergunta é para o caso
Task<T>
, no entanto, a pergunta é feita geralmente.fonte
Result
comGetIntAsync()
que retornosTask<int>
não apenasTask
. Eu sugiro que você leia minha resposta novamente.GetFooAsync(...).Result
dentro de uma função que retornaTask
. Isso agora faz sentido, já que não há Propriedades nulas em C # (Task.Result
é uma propriedade), mas é claro que você pode chamar um método nulo.Como já mencionado, se você pode usar
await
. Se você precisar executar o código de forma síncrona como você mencionou.GetAwaiter().GetResult()
,.Result
ou.Wait()
houver um risco de conflito, como muitos disseram em comentários / respostas. Como a maioria de nós gosta de oneliners, você pode usá-los para.Net 4.5<
Adquirindo um valor por meio de um método assíncrono:
Chamando de forma síncrona um método assíncrono
Nenhum problema de conflito ocorrerá devido ao uso de
Task.Run
.Fonte:
https://stackoverflow.com/a/32429753/3850405
fonte
fonte: c # 7.0 em poucas palavras
fonte