async void
is "not recommended", with one very important exception: event handlers.
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.
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);
}
Used like:
timer.Elapsed += timer_Elapsed;
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?
Addendum:
From your edit to the question:
Timer.Elapsed is I think synchronous event handler can I still attach async void
to it?
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).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…