Moja metoda powraca Task
. Chcę poczekać, aż to się skończy. Czego powinienem użyć
.Wait()
lub .GetAwaiter().GetResult()
? Jaka jest różnica między nimi?
Moja metoda powraca Task
. Chcę poczekać, aż to się skończy. Czego powinienem użyć
.Wait()
lub .GetAwaiter().GetResult()
? Jaka jest różnica między nimi?
Odpowiedzi:
Oba są synchronicznym oczekiwaniem na wynik operacji (i należy ich unikać, jeśli to możliwe).
Różnica polega głównie na obsłudze wyjątków. W Wait
przypadku ślad stosu wyjątków jest niezmieniony i reprezentuje rzeczywisty stos w momencie wystąpienia wyjątku, więc jeśli masz fragment kodu działający w wątku puli wątków, masz stos taki jak
ThreadPoolThread.RunTask
YourCode.SomeWork
Z drugiej strony, .GetAwaiter().GetResult()
zmieni ślad stosu, aby uwzględnić cały kontekst asynchroniczny, ignorując, że niektóre części kodu są wykonywane w wątku interfejsu użytkownika, a niektóre w wątku puli wątków, a niektóre są po prostu asynchronicznymi we / wy. Więc twój ślad stosu będzie odzwierciedlał synchroniczny krok w kodzie :
TheSyncMethodThatWaitsForTheAsyncMethod
YourCode.SomeAsyncMethod
SomeAsync
YourCode.SomeWork
To sprawia, że ślady stosu wyjątków są co najmniej bardziej przydatne. Możesz zobaczyć, gdzie YourCode.SomeWork
zostało wywołane w kontekście Twojej aplikacji , a nie „fizyczny sposób, w jaki została uruchomiona”.
Przykład tego, jak to działa, znajduje się w źródle referencyjnym (oczywiście poza umową).
TaskAwaiter
to szczegół implementacji. Z drugiej strony, mechanizm awaitable / awaiter jest udokumentowany i wykorzystuje pisanie typu kaczego - GetAwaiter
jest do tego, await
co GetEnumerator
jest foreach
lub Dispose
jest do using
. Wszystko to jest zdefiniowane w specyfikacji C # niezależnie od używanego konkretnego awaitera - uwaga, że Task.GetAwaiter
jest „przeznaczone raczej do użytku przez kompilator niż do użycia w kodzie aplikacji”. Ale chodzi o to, że zamierzonym zastosowaniem jest wykonanie an await
, a nie Wait()
norGetAwaiter().GetResult()
- ale GetResult
daje ładniejsze stosy, jeśli tego potrzebujesz.