Back to results for “Generic Host”
.NET › Background Services

How would you implement a periodic timer-based background task more precisely than Task.Delay, avoiding cumulative drift?

Advanced

Answer

PeriodicTimer (introduced in .NET 6) provides an async-friendly, precise interval timer via WaitForNextTickAsync(), avoiding the cumulative drift that can occur with naive Task.Delay-based loops (where the delay starts after the previous work finishes, so total cycle time = work time + delay time, drifting over many iterations) since PeriodicTimer's ticks are aligned to the original interval regardless of how long each iteration's work takes.
protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
    using var timer = new PeriodicTimer(TimeSpan.FromMinutes(5));
    while (await timer.WaitForNextTickAsync(stoppingToken)) {
        await RunScheduledJobAsync();
    }
}
Real-world example A metrics-collection background service switches from Task.Delay to PeriodicTimer to guarantee samples are taken at consistent 5-minute intervals regardless of how long each individual collection cycle takes, improving data consistency for trend analysis.

Common follow-ups: How does WaitForNextTickAsync behave if the previous tick's work takes longer than the interval?;What happens to PeriodicTimer when disposed mid-wait?