ConfigureAwait (false) odpowiednie w ASP.NET Core?

106

Natknąłem się na problem ( https://github.com/HTBox/allReady/issues/1313 ) w GitHub, gdzie dyskutowali o ConfigureAwait(false)usunięciu kodu, twierdząc, że w ASP.NET Core

wywołanie ConfigureAwait(false)jest zbędne i nic nie robi

Najlepsze, co udało mi się tutaj znaleźć, to „uwaga dodatkowa” w odpowiedzi (od Stephena Cleary, https://stackoverflow.com/a/40220190/2805831 ), która mówi, że

ASP.NET Core nie ma już „kontekstu”

Czy jest więc ConfigureAwait(false)naprawdę niepotrzebne w ASP.NET Core (nawet jeśli używasz pełnego .Net Framework)? Czy w niektórych przypadkach przynosi rzeczywisty wzrost wydajności lub różnicę w wyniku / semantyce?

EDYCJA: Czy jest inaczej w tym aspekcie, jeśli hostuję ją jako aplikację konsolową lub w usługach IIS?

Pedro Lorentz
źródło
2
Zależy to od tego, gdzie zamierzałeś go używać. Jeśli chcesz użyć go bezpośrednio w aplikacji ASP.NET Core, nie musisz go wywoływać (nie musiałeś go wywoływać w starszej wersji ASP.NET ani iirc). Ale jeśli piszesz bibliotekę, zawsze powinieneś jej używać ConfigureAwait(false), ponieważ biblioteka może być używana przez różne aplikacje (ASP.NET Core, WPF, UWP, konsola itp.)
Tseng
1
ASP.NET Core działa domyślnie jako aplikacja konsolowa, a aplikacje konsolowe AFAIK nie mają SynchronizationContext, więc tak, brzmi to rozsądnie w przypadku domyślnej aplikacji ASP.NET Core, nawet w przypadku pełnej platformy.
Joe White
@JoeWhite Ok, zredagowałem pytanie. Czy jest inaczej, jeśli moja aplikacja ASP.NET Core znajduje się w usługach IIS?
Pedro Lorentz
3
Aplikacja ASP.NET Core działająca w usługach IIS nadal działa jako aplikacja konsolowa - jedyną różnicą jest to, że usługi IIS uruchamiają i zamykają wystąpienia aplikacji (w ten sam sposób, w jaki zarządzałyby wystąpienia procesu roboczego ASP.NET w klasyczny ASP.NET). Nie zmieniłoby to żadnego zachowania związanego z wątkami w aplikacji ASP.NET. (Jedynym powodem, dla którego określiłem „domyślnie”, jest to, że można na przykład hostować ASP.NET Core w aplikacji GUI, a w takim przypadku trzeba byłoby pomyśleć o kontekście synchronizacji).
Joe White,
Uwaga ConfigureAwait(false), chociaż istotna w klasycznym ASP.NET, nie jest w żadnym wypadku konieczna . To kompromis: trochę łagodzi niektóre zakleszczenia synchronizacji przez asynchronię (które i tak są wadami projektowymi - nie istnieją, chyba że ktoś zrobi coś głupiego) i czasami ma ~ mikrosekundowy wzrost wydajności, nie ładując ponownie kontekstu. Kosztem braku możliwości polegania na kontekście i ConfigureAwaitprzechodzenia przez cały kod. stackoverflow.com/questions/28221508/…
Dax Fohl

Odpowiedzi:

113

ConfigureAwaitma wpływ tylko na kod działający w kontekście, SynchronizationContextktórego ASP.NET Core nie ma (tak jak ASP.NET „Legacy”).

Kod ogólnego przeznaczenia powinien nadal go używać, ponieważ może działać z rozszerzeniem SynchronizationContext.

ASP.NET Core SynchronizationContext

Paulo Morgado
źródło
19
Chcę tylko trochę wyjaśnić, że ASP.NET w środowisku innym niż core ma kontekst synchronizacji, ale ASP.NET core nie.
Scott Chamberlain
@Morgado, czy to prawda, nawet jeśli aplikacja jest hostowana w usługach IIS?
Pedro Lorentz
7
Aplikacja ASP.NET Core nie jest hostowana w usługach IIS. Usługi IIS działają tylko jako odwrotny serwer proxy.
Paulo Morgado
2
Zaktualizowałem odpowiedź najnowszym postem od Stephena Cleary'ego. Ale tak, ASP.NET Core to ASP.NET Core.
Paulo Morgado
14
@NamNgo. Doceniam, że jest to stary post, ale Stephen Cleary wyjaśnia to w jednym z pytań do postu, do którego Paulo dołączył powyżej. „To platforma (ASP.NET Core w przeciwieństwie do ASP.NET Classic) określa SynchronizationContext, a nie środowisko wykonawcze (.NET Core w przeciwieństwie do .NET 4.6.2)”
Gavin Sutherland
14

A co z tym?

W tej chwili (luty-2020) programiści na MS Blog zalecają użycie ConfigureAwait (false) w celu poprawy wydajności i uniknięcia zakleszczeń. https://devblogs.microsoft.com/dotnet/configureawait-faq/

Słyszałem, że ConfigureAwait (false) nie jest już potrzebne w .NET Core. Prawdziwe? Fałszywy. Jest to potrzebne w przypadku pracy na platformie .NET Core z dokładnie tych samych powodów, co w przypadku korzystania z platformy .NET Framework. W tym zakresie nic się nie zmieniło.

Alfred Severo
źródło
Jeśli jakiś kod użytkownika (lub inny kod biblioteki, którego używa Twoja aplikacja) ustawia kontekst niestandardowy i wywołuje Twój kod lub wywołuje kod w zadaniu zaplanowanym do niestandardowego TaskScheduler, to nawet w ASP.NET Core Twoje awaits mogą zobaczyć domyślny kontekst lub harmonogram, który spowodowałby, że chcesz użyć ConfigureAwait (false). Oczywiście w takich sytuacjach, jeśli unikniesz synchronicznego blokowania (którego powinieneś unikać w aplikacjach internetowych niezależnie) i jeśli nie masz nic przeciwko niewielkim narzutom wydajności w tak ograniczonych przypadkach, prawdopodobnie możesz uciec bez użycia ConfigureAwait (false) .
Alisson
2
W związku z tym powiedziałbym, że w większości przypadków nie jest to potrzebne. Chyba że używasz niestandardowego kontekstu synchronizacji lub biblioteki, która to robi.
Alisson