Can the Elapsed callback of a System.Timers.Timer be async?

David Rubin picture David Rubin · Jan 27, 2015 · Viewed 13.7k times · Source

Is it possible (or even reasonable) to make the callback of a System.Timers.Timer an async method? Something like:

var timer = new System.Timers.Timer
{
   Interval = TimeSpan.FromSeconds(30).TotalMilliseconds,
   AutoReset = true
};
timer.Elapsed += async (sender, e) => { /* await something */ };
timer.Start();

It compiles (obviously a good place to start), but I'm not sure I understand the consequences. Will the timer await the callback before resetting the timer?

Answer

Jon Skeet picture Jon Skeet · Jan 27, 2015

Will the timer await the callback before resetting the timer?

No. There's nothing it could await, because the signature of ElapsedEventHandler has a void return type.

In other words, your code is equivalent to:

var timer = new System.Timers.Timer { ... };
timer.Elapsed += Foo;
timer.Start();

...
private async void Foo()
{
    ...
}

Whether that's acceptable for you or not will depend on your context. In general, having async void methods or anonymous functions makes them harder to test and reuse - but the ability was precisely given for the sake of event handlers... You should consider how errors will be propagated though.