繁体   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