是否可以将异步事件处理程序附加到System.Timers.Timer?
我已经阅读过这里和这里发布的文章我有一个定时器事件,每隔一段时间触发一次,我想在处理程序中执行一些异步处理,所以沿着以下几行:
Timer timer = new Timer();
timer.Interval = 1000;
timer.Elapsed += timer_Elapsed; // Please ignore this line. But some answers already given based on this line so I will leave it as it is.
timer.Elapsed += async (sender, arguments) => await timer_Elapsed(sender, arguments);
private async Task timer_Elapsed(object sender, ElapsedEventArgs e)
{
await Task.Delay(10);
}
上面的代码编译和工作。
但我不确定为什么代码正在编译。 ElapsedEventHandler
预期签名是
void timer_Elapsed(object sender, ElapsedEventArgs e)
但是我的方法返回Task
而不是void
因为不建议使用async void
。 但是这与ElapsedEventHandler
签名不符,而且它仍在编译和工作?
在Timer.Elapsed上调用asyn方法可以吗? 该代码将在Windows服务中执行。
更新1
异步无效是“不推荐”,有一个非常重要的异常:事件处理程序。
如果它的异步事件处理程序或同步事件处理程序有关系吗?
MSDN文章herecsays
无效返回的异步方法有一个特定的目的:使异步事件处理程序成为可能。
Timer.Elapsed是我认为同步事件处理程序,我仍然可以将async void
附加到它?
async void
是“不推荐”,有一个非常重要的异常:事件处理程序。
你的代码编译得很好(好吧,第二个事件订阅......第一个会产生编译时错误,假设两个语句中都有相同的timer_Elapsed()
方法),因为编译器可以推断委托的返回类型应该是void
。 该async
匿名方法还可以返回Task
,但在这种情况下,这将是错误的方法签名,让你获得void
来代替。
将async void
声明为事件句柄也可以:
private async void timer_Elapsed(object sender, ElapsedEventArgs e)
{
await Task.Delay(10);
}
用途如下:
timer.Elapsed += timer_Elapsed;
对于async
方法返回void
是不理想的,但对于事件处理程序来说,没有任何代码会使用Task
(除非该事件专门用于理解async
方法,就像在C#中的异步事件一样)。 如果你从这样做中获得零利益,没有理由向后屈服以遵守那些正确的编码习惯。
另请参见我应该避免使用“异步无效”事件处理程序吗?
附录:
从你的编辑到问题:
Timer.Elapsed是我认为同步事件处理程序,我仍然可以将async void
附加到它?
事件不是异步或同步的,而是处理器本身。 这完全取决于是否使用async
并await
处理程序方法。 您可以像您的问题和我的回答中所述,使用async void
处理程序方法和Elapsed
事件,就像您可以使用任何其他事件一样(假设事件签名需要void
作为处理程序返回类型,这当然是标准对于传统的.NET事件)。
你对避免“异步无效”是正确的。 不知道编译器没有反对,但是你两次订阅相同的事件。
您应该将异步部分保留在处理程序中,而不是处理程序的调用中。
尝试删除重复的事件订阅:
timer.Elapsed += async (sender, arguments) => await timer_Elapsed(sender, arguments);
并从以下位置更改处理程序的签名:
private async Task timer_Elapsed(object sender, ElapsedEventArgs e)
至:
private void timer_Elapsed(object sender, ElapsedEventArgs e)
然后在处理程序中执行异步部分,使用类似本帖中的建议:https://stackoverflow.com/a/31469699/6776481
除了“WrapSomeMethod”调用将只返回Task
,而不是Task<string>
。
此外,由于这是在Windows服务中,所以不要忘记在必要时退订事件。
链接地址: http://www.djcxy.com/p/93009.html上一篇: Is it okay to attach async event handler to System.Timers.Timer?
下一篇: Share AI key between between multiple web apps and services?