devterview_$ iniciar simulação

Deadlock por `.Result` / `.Wait()` em código async

DifícilSêniorAssincronia

Pergunta

Por que chamar `.Result` ou `.Wait()` numa `Task` pode travar a aplicação, e qual é a forma correta?

Resposta esperada

Em contextos com SynchronizationContext (UI clássica de WinForms/WPF, ou ASP.NET pré-Core), `await` por padrão volta a continuação pra aquele contexto. Se você bloqueia a thread desse contexto com `.Result`/`.Wait()` esperando a Task terminar, e a Task precisa dessa mesma thread pra rodar a continuação, os dois se esperam pra sempre — deadlock. A forma correta é `await` da Task de ponta a ponta (`async` all the way), nunca bloquear. Em bibliotecas, `ConfigureAwait(false)` diz pra continuação não voltar ao contexto capturado, reduzindo o risco. ASP.NET Core não tem SynchronizationContext, então o deadlock específico some, mas bloquear ainda desperdiça thread do pool.

Por que perguntam isso

Pergunta pleno de C#. Sinal de domínio: nomear o SynchronizationContext e `ConfigureAwait(false)`, e saber que ASP.NET Core mudou esse cenário.

#async-await#deadlock#synchronizationcontext
publicidade

Perguntas de acompanhamento

Relacionadas