async void
事件處理程序:該不該避免?
一般來說,最佳實踐建議避免使用 async void
方法,尤其是在啟動任務時,因為它們缺乏跟踪掛起任務的機制,並且異常處理較為複雜。但是,這個原則是否也適用於 async void
事件處理程序呢?
讓我們來看一個例子:
<code class="language-csharp">private async void Form_Load(object sender, System.EventArgs e) { await Task.Delay(2000); // 执行异步操作 // ... }</code>
與其使用這種方法,不如重新設計代碼來實現任務跟踪和取消功能:
<code class="language-csharp">Task onFormLoadTask = null; // 跟踪任务,可以实现取消 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); // 执行异步操作 // ... }</code>
除了潛在的重入問題外,async void
事件處理程序還有什麼隱藏的陷阱?
關鍵在於,async void
的使用在無法優雅地處理異常的上下文中是被勸退的。然而,在事件處理程序中,異常會被路由到全局異常處理程序,確保它們被適當地捕獲和處理,無需在事件處理程序本身進行顯式錯誤處理。這就是使 async void
在這種特定情況下可以接受的關鍵區別。
為了進行單元測試,通常的做法是提取所有 async void
方法的邏輯以進行隔離:
<code class="language-csharp">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); }</code>
總之,雖然通常不建議使用 async void
方法,但在 async void
事件處理程序中使用它們是可以接受的,因為事件處理程序框架具有固有的異常處理機制。因此,您可以在事件處理程序中使用 async void
而不會違反最佳實踐。
以上是您應該避免使用 Async Void 事件處理程序嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!