Wiem, że generalnie uważane jest za zły pomysł, aby async void
uruchamiać zadania przy użyciu metod odpal i zapomnij , ponieważ nie ma ścieżki oczekującego zadania i trudno jest obsłużyć wyjątki, które mogą zostać wrzucone do takiej metody.
Czy powinienem również unikać async void
obsługi zdarzeń? Na przykład,
private async void Form_Load(object sender, System.EventArgs e)
{
await Task.Delay(2000); // do async work
// ...
}
Mogę to przepisać w ten sposób:
Task onFormLoadTask = null; // track the task, can implement cancellation
private void Form_Load(object sender, System.EventArgs e)
{
this.onFormLoadTask = OnFormLoadTaskAsync(sender, e);
}
private async Task OnFormLoadTaskAsync(object sender, System.EventArgs e)
{
await Task.Delay(2000); // do async work
// ...
}
Jakie są podwodne skały dla obsługi zdarzeń asynchronicznych, oprócz możliwego ponownego wejścia?
Odpowiedzi:
Wytyczną jest unikanie
async void
z wyjątkiem sytuacji, gdy jest używana w programie obsługi zdarzeń, więc używanieasync void
w programie obsługi zdarzeń jest OK.To powiedziawszy, z powodów związanych z testami jednostkowymi często lubię brać pod uwagę logikę wszystkich
async void
metod. Na przykład,źródło
Form_Load
dostępu dopublic
? Wygląda na to, że w ten sposób kod byłby mniej szczegółowy.OnFormLoadAsync
. Teraz widzę, że to przydatna sztuczka. Dzięki.Handled
flaga musi być ustawiona synchronicznie; nie można użyć goasync
do podjęcia decyzji, czy zdarzenie jest obsługiwane, czy nie.ICommand.Execute
metodęasync void
; Uważam to za dopuszczalne, ponieważ logicznieICommand.Execute
jest to program obsługi zdarzeń.Ogólnie rzecz biorąc, programy obsługi zdarzeń to jedyny przypadek, w którym metoda void async nie jest potencjalnym zapachem kodu.
Jeśli z jakiegoś powodu musisz śledzić zadanie, to technika, którą opisujesz, jest całkowicie rozsądna.
źródło
Tak, na ogół asynchroniczny brak obsługi zdarzeń jest jedynym przypadkiem. Jeśli chcesz dowiedzieć się więcej na ten temat, obejrzyj świetny film na kanale 9
The only case where this kind of fire-and-forget is appropriate is in top-level event-handlers. Every other async method in your code should return "async Task".
tutaj jest link
źródło
Jeśli korzystasz z ReSharper, bezpłatne rozszerzenie ReCommended może być pomocne. Analizuje metody „asynchronicznej pustki” i podkreśla, gdy są używane nieprawidłowo. Rozszerzenie może rozróżniać różne zastosowania async void i zapewniać odpowiednie szybkie poprawki opisane tutaj: wiki ReCommended-Extension .
źródło