可以将异步事件处理程序附加到System.Timers.Timer吗? [英] Is it okay to attach async event handler to System.Timers.Timer?
问题描述
我已经阅读了此处和文章此处 我有一个定时器事件,它每隔一段时间触发一次,我想在处理程序中进行一些异步处理,所以类似以下内容:
I have already read SO post here and article here I have a timer event that fires every once in a while and i want to do some asynchronous processing inside the handler, so something along the lines of:
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);
}
上面的代码可以编译和运行.
The code above compiling and working.
但是我不确定为什么要编译代码. ElapsedEventHandler
预期签名是
But I am not sure why the code is compiling. The ElapsedEventHandler
expected signature is
void timer_Elapsed(object sender, ElapsedEventArgs e)
但是我的方法返回Task
而不是void
,因为不建议使用async void
.但这与ElapsedEventHandler
签名不匹配,并且仍在编译中&工作吗?
However my method returns Task
instead of void
since async void
is not recommended. but that does not match with ElapsedEventHandler
signature and its still compiling & working?
可以在Timer.Elapsed上调用asyn方法吗?该代码将在Windows服务中执行.
Is it okay to call asyn method on Timer.Elapsed? the code will be executed inside windows service.
更新1
不建议使用异步void",但有一个非常重要的例外: 事件处理程序.
async void is "not recommended", with one very important exception: event handlers.
它的异步事件处理程序还是同步事件处理程序有关系吗?
Does it matter if its asynchronous event handler or synchronous event hander?
MSDN文章此处说明
返回无效的异步方法有一个特定的目的: 可以使用异步事件处理程序.
Void-returning async methods have a specific purpose: to make asynchronous event handlers possible.
Timer.Elapsed是我认为我仍然可以将async void
附加到同步事件处理程序吗?
Timer.Elapsed is I think synchronous event handler can I still attach async void
to it?
推荐答案
async void
不推荐",但有一个非常重要的例外:事件处理程序.
async void
is "not recommended", with one very important exception: event handlers.
您的代码可以正常编译(嗯,第二个事件subscription…假设两个语句中的timer_Elapsed()
方法都相同,则第一个事件将生成编译时错误),因为编译器可以推断出委托的返回类型应该为async
匿名方法可以也返回Task
,但是在这种情况下,这将是错误的方法签名,因此您将得到void
.
Your code compiles fine (well, the second event subscription…the first would generate a compile-time error, assuming the same timer_Elapsed()
method in both statements), because the compiler can infer the delegate's return type should be void
. The async
anonymous method could also return Task
, but in this case that would be the wrong method signature, so you get void
instead.
也可以只将事件句柄声明为async void
:
It would also be fine to just declare your event handle as async void
:
private async void timer_Elapsed(object sender, ElapsedEventArgs e)
{
await Task.Delay(10);
}
使用方式:
timer.Elapsed += timer_Elapsed;
为async
方法返回void
是不理想的,但是对于事件处理程序,无论如何都没有代码将要使用Task
(除非事件是专门为理解
Returning void
for async
methods is not ideal, but in the case of an event handler, there is no code that is going to use the Task
anyway (unless the event is specifically implemented to understand async
methods, as in Asynchronous events in C#). There's no reason to bend over backwards to comply with what would otherwise be the correct coding practice, if you get zero benefit from doing so.
See also Should I avoid 'async void' event handlers?
附录:
从您的编辑到问题:
Timer.Elapsed是我认为我仍然可以将
async void
附加到同步事件处理程序吗?
Timer.Elapsed is I think synchronous event handler can I still attach
async void
to it?
不是异步或同步的事件,而是处理程序本身.而这完全取决于您是否对处理程序方法使用async
和await
.正如您的问题和我的回答中所述,您可以将async void
处理程序方法与Elapsed
事件一起使用,就像对其他任何事件一样(假定事件签名需要void
作为处理程序返回类型,当然是常规.NET事件的标准.
It's not the event that is asynchronous or synchronous, but the handler itself. And that's determined entirely by whether you use async
and await
for the handler method. You may, as described in your question and my answer, use an async void
handler method with the Elapsed
event, just as you may with any other event (assuming the event signature requires void
as the handler return type, which is of course the standard for conventional .NET events).
这篇关于可以将异步事件处理程序附加到System.Timers.Timer吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!