ZetCode

C# PeriodicTimer

last modified October 5, 2026

This article explains how to use PeriodicTimer to run asynchronous work at regular intervals. The type is available in .NET 6 and later and is defined in System.Threading.

Unlike a callback-based timer, PeriodicTimer can be consumed with await. A single consumer waits for each tick with WaitForNextTickAsync, which returns false when the timer is disposed.

C# PeriodicTimer example

The following program waits for three ticks. The first tick arrives after the interval elapses, and each successful wait continues the loop.

Program.cs
using System;
using System.Threading;

using var timer = new PeriodicTimer(TimeSpan.FromSeconds(1));
var count = 0;

while (count < 3 && await timer.WaitForNextTickAsync())
{
    count++;
    Console.WriteLine($"Tick {count}");
}
$ dotnet run
Tick 1
Tick 2
Tick 3

The ticks are asynchronous; the calling thread is not blocked while waiting. A periodic timer does not queue an unlimited number of missed ticks. If the consumer is late, ticks can coalesce.

Stopping a timer with cancellation

Pass a cancellation token to WaitForNextTickAsync to stop the wait. Cancellation ends that wait by throwing OperationCanceledException, so handle cancellation where appropriate.

Program.cs
using System;
using System.Threading;

using var timer = new PeriodicTimer(TimeSpan.FromSeconds(1));
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3));

try
{
    while (await timer.WaitForNextTickAsync(cts.Token))
    {
        Console.WriteLine("Working");
    }
}
catch (OperationCanceledException)
{
    Console.WriteLine("Stopped");
}

The cancellation token cancels the pending wait; disposing the timer also causes the wait to return false. Dispose the timer when the periodic work is finished.

PeriodicTimer notes

Source

PeriodicTimer Class - .NET API

This article introduced periodic asynchronous waits in C#.

Author

Jan Bodnar writes programming tutorials and educational content.

List all C# tutorials.