W jakich scenariuszach chcielibyśmy skorzystać
public async Task AsyncMethod(int num)
zamiast
public async void AsyncMethod(int num)
Jedyny scenariusz, o którym mogę pomyśleć, to jeśli potrzebujesz zadania, aby móc śledzić jego postępy.
Ponadto w poniższej metodzie asynchronizacja i oczekiwanie na słowa kluczowe są niepotrzebne?
public static async void AsyncMethod2(int num)
{
await Task.Factory.StartNew(() => Thread.Sleep(num));
}
c#
asynchronous
.net-4.5
użytkownik981225
źródło
źródło
Foo()
byłoby staćFooAsync()
.Thread.Sleep
w swoich zadaniach, powinieneśawait Task.Delay(num)
zamiast tegoTask.Delay
nie jestTask.AsyncDelay
jak wszystkie metody na zadania są asynchronicznyasync void
zamiastasync Task
. Metoda uległa awarii, ponieważ korzystała z obiektu kontekstowego Entity Framework zadeklarowanego jako element kontrolera, zanim została zakończona metoda. Środowisko rozproszyło kontroler, zanim zakończyła się jego metoda wykonywania. Zmieniłem metodę na asynchronizującą Zadanie i zadziałało.Odpowiedzi:
1) Zwykle chciałbyś zwrócić a
Task
. Głównym wyjątkiem powinno być, kiedy trzeba miećvoid
typ zwracany (dla zdarzeń). Jeśli nie ma powodu, by odmawiać dzwoniącemuawait
zadania, dlaczego miałbyś to robić?2)
async
metody, które powracają,void
są wyjątkowe w innym aspekcie: reprezentują operacje asynchroniczne najwyższego poziomu i mają dodatkowe reguły, które wchodzą w grę, gdy zadanie zwróci wyjątek. Najłatwiej jest pokazać różnicę na przykładzie:f
wyjątek jest zawsze „przestrzegany”. Wyjątek, który pozostawia metodę asynchroniczną najwyższego poziomu, jest po prostu traktowany jak każdy inny nieobsługiwany wyjątek.g
wyjątek nigdy nie jest przestrzegany. Gdy śmieciarz przychodzi, aby wyczyścić zadanie, widzi, że zadanie spowodowało wyjątek i nikt nie obsługiwał wyjątku. Kiedy tak się dzieje, programTaskScheduler.UnobservedTaskException
obsługi działa. Nigdy nie powinieneś na to pozwolić. Aby użyć swojego przykładu,Tak, użyj
async
iawait
tutaj, upewnij się, że twoja metoda nadal działa poprawnie, jeśli zostanie zgłoszony wyjątek.Aby uzyskać więcej informacji, zobacz: http://msdn.microsoft.com/en-us/magazine/jj991977.aspx
źródło
f
zamiastg
w moim komentarzu. Wyjątek odf
jest przekazywany doSynchronizationContext
.g
wzrośnieUnobservedTaskException
, aleUTE
nie powoduje już awarii procesu, jeśli nie jest obsługiwany. Istnieją sytuacje, w których dopuszczalne są takie „wyjątki asynchroniczne”, które są ignorowane.WhenAny
wieleTask
s, co powoduje wyjątki. Często musisz tylko poradzić sobie z pierwszym i często chcesz zignorować pozostałe.WhenAny
w pierwszej kolejności, czy w porządku jest zignorowanie innych wyjątków: główny przypadek użycia, który mam dla niego, wciąż kończy się na pozostałych zadaniach po zakończeniu , z wyjątkiem lub bez wyjątku.Mam natknąć się tym bardzo przydatny artykuł na temat
async
ivoid
napisany przez Jérôme Labana: https://jaylee.org/archive/2012/07/08/c-sharp-async-tips-and-tricks-part-2-async-void .htmlNajważniejsze jest to, że system
async+void
może spowodować awarię systemu i zwykle powinien być używany tylko w procedurach obsługi zdarzeń po stronie interfejsu użytkownika.źródło
Z tego stwierdzenia jasno zrozumiałem.
Wyjątków od metody Async Void nie można złapać za pomocą Catch
Te wyjątki można zaobserwować za pomocą AppDomain.UnhandledException lub podobnego zdarzenia catch-all dla aplikacji GUI / ASP.NET, ale użycie tych zdarzeń do regularnej obsługi wyjątków jest receptą na niemożność konserwacji (powoduje awarię aplikacji).
Metody asynchronicznej pustki mają różną semantykę komponowania. Metody asynchroniczne zwracające Zadanie lub Zadanie można łatwo skomponować za pomocą funkcji Oczekuj, Task.WhenAny, Task.WhenAll itd. Zwracane nieważne metody asynchroniczne nie zapewniają łatwego sposobu powiadamiania o zakończeniu kodu wywołującego. Łatwo jest uruchomić kilka asynchronicznych metod void, ale nie jest łatwo ustalić, kiedy skończą. Metody asynchroniczne void powiadomią o swoim SynchronizationContext, gdy zaczną i zakończą, ale niestandardowy SynchronizationContext to złożone rozwiązanie dla zwykłego kodu aplikacji.
Metoda Async Void przydatna podczas korzystania z synchronicznej procedury obsługi zdarzeń, ponieważ zgłaszają one wyjątki bezpośrednio w SynchronizationContext, który jest podobny do zachowania synchronicznych procedur obsługi zdarzeń
Aby uzyskać więcej informacji, sprawdź ten link https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
źródło
Problem z wywoływaniem asynchronicznej nieważności polega na tym, że nawet nie odzyskujesz zadania, nie możesz wiedzieć, kiedy zadanie zostało zakończone (patrz https://blogs.msdn.microsoft.com/oldnewthing/20170720-00/ p = 96655 )
Oto trzy sposoby wywołania funkcji asynchronicznej:
źródło
Myślę, że możesz użyć go również
async void
do rozpoczęcia operacji w tle, o ile będziesz uważać na wyjątki. Myśli?źródło
Moja odpowiedź jest prosta: nie możesz oczekiwać nieważnej metody
Więc jeśli metoda jest asynchroniczna, lepiej być wyczekiwanym, ponieważ możesz stracić przewagę asynchroniczną.
źródło
Według dokumentacji Microsoft NIGDY nie należy używać
async void
źródło