ConfigureAwait (false) relevant in ASP.NET Core?

98

Ich bin über ein Problem gestolpert ( bei GitHub https://github.com/HTBox/allReady/issues/1313 ), bei dem es darum ging, ConfigureAwait(false)den Code in ASP.NET Core zu entfernen und dies zu behaupten

Der Aufruf von ConfigureAwait(false)ist redundant und führt zu nichts

Das Beste, was ich hier finden konnte, ist eine „Randnotiz“ in einer Antwort (von Stephen Cleary, https://stackoverflow.com/a/40220190/2805831 ), die dies sagt

ASP.NET Core hat keinen "Kontext" mehr

Also, ist ConfigureAwait(false)wirklich unnötig in ASP.NET - Core (auch wenn vollständige .NET Framework)? Hat es in einigen Fällen einen echten Leistungsgewinn oder einen Unterschied im Ergebnis / in der Semantik?

BEARBEITEN: Ist es in diesem Aspekt anders, wenn ich es als Konsolenanwendung oder in IIS hoste?

Pedro Lorentz
quelle
2
Dies hängt davon ab, wo Sie es verwenden möchten. Wenn Sie es direkt in Ihrer ASP.NET Core-Anwendung verwenden möchten, müssen Sie es nicht aufrufen (Sie mussten es weder in ASP.NET Legacy noch in iirc aufrufen). Wenn Sie jedoch eine Bibliothek schreiben, sollten Sie diese immer verwenden ConfigureAwait(false), da die Bibliothek von verschiedenen Anwendungen (ASP.NET Core, WPF, UWP, Konsole usw.) verwendet werden kann
Tseng
1
ASP.NET Core wird standardmäßig als Konsolenanwendung ausgeführt, und AFAIK-Konsolenanwendungen verfügen nicht über einen SynchronizationContext. Ja, dies klingt für eine Standardanwendung von ASP.NET Core auch mit dem vollständigen Framework sinnvoll.
Joe White
@ JoeWhite Ok, habe die Frage bearbeitet. Ist es anders, wenn sich meine ASP.NET Core-App in IIS befindet?
Pedro Lorentz
3
Eine ASP.NET Core-App, die in IIS ausgeführt wird, wird weiterhin als Konsolenanwendung ausgeführt. Der einzige Unterschied besteht darin, dass IIS Instanzen Ihrer App startet und herunterfährt (genauso wie es Instanzen des ASP.NET-Arbeitsprozesses in verwaltet hätte klassisches ASP.NET). Es würde kein threadbezogenes Verhalten in Ihrer ASP.NET-App ändern. (Der einzige Grund , warum ich „by default“ angegeben ist , dass Sie könnte zum Beispiel Host ASP.NET - Core in einer GUI - Anwendung, und in diesem Fall , dass Sie würde über den Synchronisations Kontext denken.)
Joe White
Beachten Sie ConfigureAwait(false), dass dies in ASP.NET classic zwar relevant , aber keinesfalls erforderlich ist . Es ist ein Kompromiss: Es mildert einige Sync-over-Async-Deadlocks (die sowieso Designfehler sind - sie existieren nur, wenn jemand etwas Dummes tut) und hat gelegentlich eine Leistungssteigerung von ~ Mikrosekunden, indem der Kontext nicht neu geladen wird. Auf Kosten, nicht vom Kontext abhängig zu sein und ConfigureAwaitalles durch Ihren Code zu haben. stackoverflow.com/questions/28221508/…
Dax Fohl

Antworten:

102

ConfigureAwaithat nur Auswirkungen auf Code, der in einem Kontext ausgeführt wird, SynchronizationContextden ASP.NET Core nicht hat (ASP.NET "Legacy").

Allzweckcode sollte ihn weiterhin verwenden, da er möglicherweise mit a ausgeführt wird SynchronizationContext.

ASP.NET Core SynchronizationContext

Paulo Morgado
quelle
17
Ich möchte nur eine kleine Klarstellung machen: ASP.NET in einer Umgebung ohne Kern hat einen Synchronisierungskontext, ASP.NET-Kern jedoch nicht.
Scott Chamberlain
@Morgado, ist es wahr, auch wenn die App in IIS gehostet wird?
Pedro Lorentz
7
Eine ASP.NET Core-App wird nicht in IIS gehostet. IIS fungiert nur als Reverse-Proxy.
Paulo Morgado
2
Ich habe die Antwort mit einem kürzlich veröffentlichten Beitrag von Stephen Cleary aktualisiert. Aber ja, ASP.NET Core ist ASP.NET Core.
Paulo Morgado
14
@NamNgo. Schätzen Sie, dass dies jetzt ein alter Beitrag ist, aber Stephen Cleary stellt dies in einer der Fragen zu dem Beitrag klar , den Paulo oben verlinkt hat. "Es ist das Framework (ASP.NET Core im Gegensatz zu ASP.NET Classic), das den SynchronizationContext bestimmt, nicht die Laufzeit (.NET Core im Gegensatz zu .NET 4.6.2)"
Gavin Sutherland,
14

Was ist damit?

In diesem Moment (Februar 2020) empfehlen Entwickler auf MS Blog die Verwendung von ConfigureAwait (false), um die Leistung zu verbessern und Deadlocks zu vermeiden. https://devblogs.microsoft.com/dotnet/configureawait-faq/

Ich habe gehört, dass ConfigureAwait (false) in .NET Core nicht mehr erforderlich ist. Wahr? Falsch. Es wird für die Ausführung unter .NET Core aus genau den gleichen Gründen benötigt, aus denen es unter .NET Framework ausgeführt wird. Daran hat sich nichts geändert.

Alfred Severo
quelle
Wenn ein Benutzercode (oder ein anderer Bibliothekscode, den Ihre App verwendet) einen benutzerdefinierten Kontext festlegt und Ihren Code aufruft oder Ihren Code in einer Aufgabe aufruft, die für einen benutzerdefinierten TaskScheduler geplant ist, wird in Ihren Wartezeiten möglicherweise auch in ASP.NET Core ein Nicht-Code angezeigt. Standardkontext oder Scheduler, der dazu führen würde, dass Sie ConfigureAwait (false) verwenden möchten. In solchen Situationen können Sie natürlich ohne ConfigureAwait (false) davonkommen, wenn Sie das synchrone Blockieren vermeiden (was Sie in Web-Apps unabhängig davon vermeiden sollten) und wenn Sie den geringen Leistungsaufwand in solch begrenzten Fällen nicht stören. .
Alisson
Demnach würde ich sagen, dass es in den meisten Fällen nicht benötigt wird. Es sei denn, Sie verwenden einen benutzerdefinierten Synchronisationskontext oder eine Bibliothek, die dies tut.
Alisson