Search code examples
c#.net-6.0background-service.net-7.0periodictimer

PeriodicTimer with dynamic period in a BackgroundService


I'm using

using PeriodicTimer timer = new(_period);

while (!stoppingToken.IsCancellationRequested
    && await timer.WaitForNextTickAsync(stoppingToken))
{
    await DoWork();
}

Is there a way to set _period dynamically? that is, take that period of a database for example.


Solution

  • A new property PeriodicTimer.Period has been introduced on .NET 8:

    Gets or sets the period between ticks.

    Originally this answer contained a custom UpdateablePeriodicTimer implementation, featuring the (then lacking) Period property. In case you are targeting .NET 6 or 7, you can find it in the 1st revision of this answer. I am no longer satisfied with that implementation though, because when I wrote it I was not aware of a by design behavior of the PeriodicTimer class:

    This is by design. The timer starts when the instance is created, not when you call WaitForNextTickAsync. If the timer ticks before the call, it'll complete immediately. That's true even when it's not the first, eg if you call Wait and it completes, then you go away for longer than the period, the next call to Wait will also likely complete immediately.