将异步事件处理程序附加到 System.Timers.Timer 可以吗? [英] Is it okay to attach async event handler to System.Timers.Timer?

查看:17
本文介绍了将异步事件处理程序附加到 System.Timers.Timer 可以吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在这里阅读了SO帖子 和文章 此处.我有一个定时器事件,它每隔一段时间就会触发一次,我想在处理程序中进行一些异步处理,因此类似于以下内容:

I have already read the SO posts 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 is 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 yet it's still compiling and working?

可以在 Timer.Elapsed 上调用异步方法吗?代码将在 Windows 服务中执行.

Is it okay to call an async method on Timer.Elapsed? The code will be executed inside a Windows service.

更新 1

async void 是不推荐"的,有一个非常重要的例外:事件处理程序.

async void is "not recommended", with one very important exception: event handlers.

它是异步事件处理程序还是同步事件处理程序重要吗?

Does it matter if it's an asynchronous event handler or synchronous event hander?

一篇 MSDN 文章 此处 说:

An MSDN article here says:

返回空的异步方法有一个特定的目的:使可以使用异步事件处理程序.

Void-returning async methods have a specific purpose: to make asynchronous event handlers possible.

Timer.Elapsed 是我认为的同步事件处理程序;我还可以将 async void 附加到它吗?

Timer.Elapsed is I think a 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.

您的代码编译良好(好吧,第二个事件订阅…第一个会生成编译时错误,假设两个语句中的 timer_Elapsed() 方法相同),因为编译器可以推断委托的返回类型应该是 void.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 无论如何(除非该事件专门用于理解 async 方法,如 C# 中的异步事件).如果您从中获得零收益,就没有理由为了遵守正确的编码实践而退缩.

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.


另请参阅我应该避免使用async void"事件处理程序吗?


附录:

从您的编辑到问题:

Timer.Elapsed 是我认为同步事件处理程序我仍然可以将 async void 附加到它吗?

Timer.Elapsed is I think synchronous event handler can I still attach async void to it?

异步或同步的不是事件,而是处理程序本身.这完全取决于您是否使用 asyncawait 作为处理程序方法.如您的问题和我的回答所述,您可以将 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆