[英]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.