簡體   English   中英

我應該避免“async void”事件處理程序嗎?

[英]Should I avoid 'async void' event handlers?

我知道使用即發即async void方法來啟動任務通常被認為是一個壞主意,因為沒有掛起任務的跟蹤,並且處理可能在這種方法中拋出的異常很棘手。

我通常也應該避免使用async void事件處理程序嗎? 例如,

private async void Form_Load(object sender, System.EventArgs e)
{
        await Task.Delay(2000); // do async work
        // ...
} 

我可以像這樣重寫它:

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
        // ...
} 

除了可能的重入之外,異步事件處理程序的水下岩石是什么?

准則是避免async void除非在事件處理程序中使用,因此在事件處理程序中使用async void是可以的。

也就是說,出於單元測試的原因,我經常喜歡將所有async void方法的邏輯async void出來。 例如,

public async Task OnFormLoadAsync(object sender, EventArgs e)
{
  await Task.Delay(2000);
  ...
}

private async void Form_Load(object sender, EventArgs e)
{
  await OnFormLoadAsync(sender, e);
}

我通常也應該避免使用 async void 事件處理程序嗎?

通常,事件處理程序是一種無效異步方法不是潛在代碼異味的情況。

現在,如果您出於某種原因確實需要跟蹤任務,那么您描述的技術是完全合理的。

是的,通常 async void of event handlers 是唯一的情況。 如果您想了解更多信息,可以在第 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".

這是鏈接

如果您使用 ReSharper,免費的ReCommended Extension可能對您有所幫助。 它分析“異步無效”方法並在使用不當時突出顯示。 該擴展可以區分異步無效的不同用法,並提供此處描述的適當的快速修復: ReCommended-Extension wiki

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM