[英]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);
您還應該看看這兩篇文章,因為異步事件處理程序經常出現問題,例如死鎖:
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.