簡體   English   中英

將異步任務定義為 windows forms 組件的事件的后果是什么?

[英]What are the consequences of defining async task as event of a windows forms component?

這是一個常識,我們不應該在代碼周圍的正常方法上使用async void ,但有一些例外,例如 winforms(或 WPF)組件的 EventHandlers:

public async void OnButtonClicked(object sender, EventArgs args)
{
    await DoSomethingAsync();
}

但是做這樣的事情會有什么后果呢?

button.OnClick += async (obj, e) => await AsyncTaskButtonClickEvent(obj ,e);

async Task AsyncTaskButtonClickEvent(object sender, EventArgs args) {  }
...

在您的第二個示例中,您創建了一個 lambda 調用具有完全相同簽名的方法,這沒有多大意義。 也許你的意思是讓它像下面這樣:

button.OnClick += async (obj, e) => await DoSomethingAsync();

假設您這樣做了,唯一的區別是您將方法與 lambda 進行比較。 我建議閱讀C# Lambda 表達式:我為什么要使用它們? 了解差異。

在事件處理程序中使用async void是唯一的方法。 這就是允許 async void 的原因,因此您可以將事件處理程序連接到異步方法。 鑒於事件處理程序委托簽名是這樣的,使用async Task將導致編譯器錯誤:

public delegate void EventHandler(object sender, EventArgs e);

您還應該看看這兩篇文章,因為異步事件處理程序經常出現問題,例如死鎖:

Async/Await - 異步編程的最佳實踐

https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

兩者是等價的但是。 async void是眾所周知的“錯誤蜂巢”。 如果您 go 一直異步,並且遇到兩個線程同時訪問某些內容的問題,您可能需要從正則表達式搜索“async void”開始調試。 第一個示例將直接引導您找到源代碼。 第二個完全沒有。 我更喜歡第一個,因為它帶有危險標志。

暫無
暫無

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

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