ConfigureAwait (false) rilevante in ASP.NET Core?


101

Mi sono imbattuto in un problema ( https://github.com/HTBox/allReady/issues/1313 ) su GitHub dove hanno discusso sull'estrazione ConfigureAwait(false)del codice, sostenendo che, in ASP.NET Core

la chiamata a ConfigureAwait(false)è ridondante e non fa nulla

Il meglio che ho trovato qui è una "nota a margine" in una risposta (da Stephen Cleary, https://stackoverflow.com/a/40220190/2805831 ) che dice che

ASP.NET Core non ha più un "contesto"

Quindi, è ConfigureAwait(false)davvero inutile in ASP.NET Core (anche se si utilizza .Net Framework completo)? In alcuni casi ha un reale guadagno in termini di prestazioni o differenze nel risultato / semantico?

EDIT: è diverso in questo aspetto se lo sto ospitando come applicazione console o in IIS?


2
Dipende da dove avevi intenzione di usarlo. Se volevi usarlo direttamente nella tua applicazione ASP.NET Core, allora no, non devi chiamarlo (non dovevi chiamarlo in ASP.NET legacy né iirc). Ma se si scrive una libreria, allora si dovrebbe sempre usare ConfigureAwait(false), come la libreria può essere consumato da diverse applicazioni (ASP.NET core, WPF, UWP, Consolle, ecc)
Tseng

1
ASP.NET Core viene eseguito come applicazione console per impostazione predefinita e le applicazioni console AFAIK non hanno un SynchronizationContext, quindi sì, questo sembra ragionevole per un'applicazione ASP.NET Core predefinita, anche con il Framework completo.
Joe White

@ JoeWhite Ok, ho modificato la domanda. È diverso se la mia app ASP.NET Core è in IIS?
Pedro Lorentz

3
Un'app ASP.NET Core in esecuzione in IIS viene comunque eseguita come applicazione console: l'unica differenza è che IIS sta avviando e arrestando le istanze dell'app (allo stesso modo in cui avrebbe gestito le istanze del processo di lavoro ASP.NET in classico ASP.NET). Non cambierebbe alcun comportamento relativo ai thread all'interno della tua app ASP.NET. (L'unico motivo ho specificato "per difetto" è che si potrebbe, ad esempio, ospita ASP.NET core all'interno di un'applicazione GUI, e in questo caso si sarebbe dovuto pensare al contesto di sincronizzazione.)
Joe White

Nota ConfigureAwait(false), sebbene rilevante in ASP.NET classico, non è affatto necessario . È un compromesso: mitiga alcuni deadlock di sincronizzazione su asincrono (che sono comunque difetti di progettazione - non esistono a meno che qualcuno non faccia qualcosa di stupido) e occasionalmente ha un aumento delle prestazioni di ~ microsecondi non ricaricando il contesto. A costo di non poter dipendere dal contesto e di avere ConfigureAwaittutto attraverso il tuo codice. stackoverflow.com/questions/28221508/...
Dax Fohl

Risposte:


106

ConfigureAwaitha effetti solo sul codice in esecuzione nel contesto di un SynchronizationContextASP.NET Core non ha (ASP.NET "Legacy" lo fa).

Il codice generico dovrebbe comunque usarlo perché potrebbe essere in esecuzione con un file SynchronizationContext.

ASP.NET Core SynchronizationContext


17
Voglio solo mettere un leggero chiarimento, ASP.NET in un ambiente non core ha un contesto di sincronizzazione, ma ASP.NET core no.
Scott Chamberlain

@Morgado, è vero anche se l'app è ospitata in IIS?
Pedro Lorentz

7
Un'app ASP.NET Core non è ospitata in IIS. IIS agisce proprio come un proxy inverso.
Paulo Morgado

2
Ho aggiornato la risposta con un recente post di Stephen Cleary. Ma sì, ASP.NET Core è ASP.NET Core.
Paulo Morgado

14
@NamNgo. Apprezzo che questo sia un vecchio post ora, ma Stephen Cleary lo chiarisce in una delle domande sul post che Paulo ha collegato sopra. "è il framework (ASP.NET Core al contrario di ASP.NET Classic) che determina il SynchronizationContext, non il runtime (.NET Core al contrario di .NET 4.6.2)"
Gavin Sutherland

14

Che dire di questo?

In questo momento (febbraio 2020) gli sviluppatori su MS Blog consigliano di utilizzare ConfigureAwait (false) per migliorare le prestazioni ed evitare deadlock. https://devblogs.microsoft.com/dotnet/configureawait-faq/

Ho sentito che ConfigureAwait (false) non è più necessario in .NET Core. Vero? Falso. È necessario quando si esegue su .NET Core esattamente per gli stessi motivi per cui è necessario quando si esegue su .NET Framework. Niente è cambiato in questo senso.


Se un codice utente (o un altro codice di libreria utilizzato dall'app) imposta un contesto personalizzato e chiama il codice o richiama il codice in un'attività pianificata per un TaskScheduler personalizzato, anche in ASP.NET Core le tue attese potrebbero vedere un contesto o scheduler predefinito che indurrebbe a voler utilizzare ConfigureAwait (false). Ovviamente, in tali situazioni, se eviti il ​​blocco sincrono (cosa che dovresti evitare di fare nelle app Web a prescindere) e se non ti dispiace i piccoli sovraccarichi di prestazioni in casi così limitati, puoi probabilmente farla franca senza usare ConfigureAwait (false) .
Alisson

1
In base a ciò, direi che per la maggior parte dei casi non è necessario. A meno che tu non stia utilizzando un contesto di sincronizzazione personalizzato o una libreria che lo fa.
Alisson
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.