Aktualizacja: ASP.NET Core nie maSynchronizationContext
. Jeśli korzystasz z ASP.NET Core, nie ma znaczenia, czy używasz, ConfigureAwait(false)
czy nie.
W przypadku ASP.NET „Full”, „Classic” lub cokolwiek, reszta tej odpowiedzi nadal obowiązuje.
Oryginalny post (dla nie-Core ASP.NET):
Ten film wideo zespołu ASP.NET zawiera najlepsze informacje na temat korzystania async
z ASP.NET.
Przeczytałem, że jest bardziej wydajny, ponieważ nie musi przełączać kontekstów wątków z powrotem do oryginalnego kontekstu wątków.
Dotyczy to aplikacji interfejsu użytkownika, w których istnieje tylko jeden wątek interfejsu użytkownika, do którego należy „zsynchronizować”.
W ASP.NET sytuacja jest nieco bardziej złożona. Gdy async
metoda wznawia wykonywanie, pobiera wątek z puli wątków ASP.NET. Jeśli wyłączysz przechwytywanie kontekstu za pomocą ConfigureAwait(false)
, wątek będzie kontynuował bezpośrednie wykonywanie metody. Jeśli nie wyłączysz przechwytywania kontekstu, wątek ponownie wejdzie w kontekst żądania, a następnie będzie kontynuował wykonywanie metody.
Więc ConfigureAwait(false)
nie oszczędza ci skoku wątku w ASP.NET; oszczędza ci to ponownego wprowadzania kontekstu żądania, ale zwykle jest to bardzo szybkie. ConfigureAwait(false)
może być przydatne, jeśli próbujesz wykonać niewielką ilość równoległego przetwarzania żądania, ale tak naprawdę TPL lepiej pasuje do większości tych scenariuszy.
Jednak w przypadku interfejsu ASP.NET Web Api, jeśli twoje zapytanie przychodzi do jednego wątku, a ty czekasz na jakąś funkcję i wywołujesz ConfigureAwait (false), który może potencjalnie umieścić cię w innym wątku, gdy zwracasz końcowy wynik funkcji ApiController .
Właściwie po prostu robienie i await
może to zrobić. Gdy twoja async
metoda trafi na await
, metoda jest blokowana, ale wątek wraca do puli wątków. Gdy metoda jest gotowa do kontynuacji, dowolny wątek jest pobierany z puli wątków i używany do wznowienia metody.
Jedyną różnicą ConfigureAwait
w ASP.NET jest to, czy wątek wchodzi w kontekst żądania podczas wznawiania metody.
Mam więcej podstawowych informacji w moim artykule MSDNSynchronizationContext
i moim async
blogu wprowadzającym .
HttpContext.Current
przepływa przez ASP.NETSynchronizationContext
, który przepływa domyślnie, gdy Tyawait
, ale nie przepływa przezContinueWith
. OTOH, kontekst wykonania (w tym ograniczenia bezpieczeństwa) to kontekst wymieniony w CLR za pośrednictwem C #, i jest przepuszczany przez obaContinueWith
iawait
(nawet jeśli używaszConfigureAwait(false)
).