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

查看:146
本文介绍了可以将异步事件处理程序附加到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(除非事件是专门为理解方法,如 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.


另请参见我应该避免使用异步无效"事件处理程序吗?


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?

不是异步或同步的事件,而是处理程序本身.而这完全取决于您是否对处理程序方法使用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天全站免登陆