ConfigureAwait (false) relevante no ASP.NET Core?

101

Me deparei com um problema ( https://github.com/HTBox/allReady/issues/1313 ) no GitHub, onde eles discutiram sobre como tirar ConfigureAwait(false)o código do código, alegando que, no ASP.NET Core

a chamada para ConfigureAwait(false)é redundante e não faz nada

O melhor que pude encontrar aqui é uma "observação lateral" em uma resposta (de Stephen Cleary, https://stackoverflow.com/a/40220190/2805831 ) dizendo que

ASP.NET Core não tem mais um "contexto"

Então, é ConfigureAwait(false)realmente desnecessário no ASP.NET Core (mesmo usando o .NET Framework completo)? Tem algum ganho real de desempenho em alguns casos ou diferença no resultado / semântica?

EDIT: É diferente neste aspecto se eu estou hospedando-o como um aplicativo de console ou no IIS?

Pedro Lorentz
fonte
2
Isso depende de onde você estava planejando usá-lo. Se você quiser usá-lo diretamente em seu aplicativo ASP.NET Core, não, você não precisa chamá-lo (você não precisa chamá-lo no ASP.NET legacy nem iirc). Mas se você escrever uma biblioteca, deve sempre usá-la ConfigureAwait(false), pois a biblioteca pode ser consumida por diferentes aplicativos (ASP.NET Core, WPF, UWP, Console etc.)
Tseng
1
O ASP.NET Core é executado como um aplicativo de console por padrão, e os aplicativos de console AFAIK não têm um SynchronizationContext, portanto, sim, isso parece razoável para um aplicativo ASP.NET Core padrão, mesmo com o Framework completo.
Joe White
@JoeWhite Ok, editou a pergunta. É diferente se meu aplicativo ASP.NET Core estiver no IIS?
Pedro Lorentz
3
Um aplicativo ASP.NET Core em execução no IIS ainda é executado como um aplicativo de console - a única diferença é que o IIS está iniciando e encerrando instâncias de seu aplicativo (da mesma forma que teria gerenciado instâncias do processo de trabalho ASP.NET em ASP.NET clássico). Isso não mudaria nenhum comportamento relacionado a thread dentro do seu aplicativo ASP.NET. (O único motivo pelo qual especifiquei "por padrão" é que você poderia, por exemplo, hospedar o ASP.NET Core dentro de um aplicativo GUI e, nesse caso , teria que pensar no contexto de sincronização.)
Joe White
Observe que ConfigureAwait(false), embora seja relevante no ASP.NET clássico, não é de forma alguma necessário . É uma troca: meio que mitiga alguns deadlocks de sincronização sobre as sincronizações (que são falhas de design de qualquer maneira - eles não existem a menos que alguém faça algo estúpido) e ocasionalmente tem um aumento de desempenho de ~ microssegundos por não recarregar o contexto. Ao custo de não poder depender do contexto e de ter ConfigureAwaittudo por meio de seu código. stackoverflow.com/questions/28221508/…
Dax Fohl

Respostas:

106

ConfigureAwaittem efeitos apenas no código em execução no contexto de um SynchronizationContextque o ASP.NET Core não tem (o ASP.NET "Legado" tem).

O código de uso geral ainda deve usá-lo porque pode estar sendo executado com um SynchronizationContext.

ASP.NET Core SynchronizationContext

Paulo Morgado
fonte
17
Só quero fazer um pequeno esclarecimento, o ASP.NET em um ambiente não principal tem um contexto de sincronização, mas o ASP.NET core não.
Scott Chamberlain
@Morgado, é verdade mesmo que o aplicativo esteja hospedado no IIS?
Pedro Lorentz
7
Um aplicativo ASP.NET Core não está hospedado no IIS. O IIS está atuando apenas como um proxy reverso.
Paulo Morgado
2
Eu atualizei a resposta com um post recente de Stephen Cleary. Mas, sim, ASP.NET Core é ASP.NET Core.
Paulo Morgado,
14
@NamNgo. Agradeço que este seja um post antigo agora, mas Stephen Cleary esclarece isso em uma das perguntas no post que Paulo vinculou acima. "é a estrutura (ASP.NET Core em oposição ao ASP.NET Classic) que determina o SynchronizationContext, não o tempo de execução (.NET Core em oposição ao .NET 4.6.2)"
Gavin Sutherland
14

Que tal isso?

No momento (Fev-2020), os desenvolvedores do MS Blog recomendam o uso de ConfigureAwait (false) para melhorar o desempenho, evitando deadlocks. https://devblogs.microsoft.com/dotnet/configureawait-faq/

Ouvi dizer que ConfigureAwait (false) não é mais necessário no .NET Core. Verdade? Falso. É necessário quando executado no .NET Core exatamente pelos mesmos motivos pelos quais é necessário quando executado no .NET Framework. Nada mudou a esse respeito.

Alfred Severo
fonte
Se algum código de usuário (ou outro código de biblioteca que seu aplicativo está usando) define um contexto personalizado e chama seu código, ou invoca seu código em uma Tarefa agendada para um TaskScheduler personalizado, mesmo no ASP.NET Core suas esperas podem ver um não contexto padrão ou agendador que levaria você a querer usar ConfigureAwait (false). Claro, em tais situações, se você evitar o bloqueio síncrono (o que você deve evitar fazer em aplicativos da web independentemente) e se você não se importar com as pequenas sobrecargas de desempenho em tais ocorrências limitadas, você provavelmente pode escapar sem usar ConfigureAwait (falso) .
Alisson
1
De acordo com isso, eu diria que na maioria dos casos não é necessário. A menos que você esteja usando um contexto de sincronização personalizado ou uma biblioteca que o faça.
Alisson