.Net provides lots of types of Timer classes that you, as a developer, probably have come across in your day-to-day work. Below is the list:
    System.Web.UI.Timer
    System.Windows.Forms.Timer
    System.Timers.Timer
    System.Threading.Timer
    System.Windows.Threading.DispatcherTimer


.NET 6 introduces one more timer class, called PeriodicTimer. It doesn't rely on callbacks and instead waits asynchronously for timer ticks. So, if you don't want to use the callbacks as it has their own flaws WaitForNextTickAsync is a good alternative.

You can create the new PeriodicTimer instance by passing the one argument Period, the time interval in milliseconds between invocations
// create a new instance of PeriodicTimer which ticks after 1 second interval
PeriodicTimer secondTimer = new PeriodicTimer(new TimeSpan(0, 0, 1));


How to use Periodic Timer
You can call the WaitForNextTickAsync method in an infinite for or while loop to wait asynchronously between ticks.
while (await secondTimer.WaitForNextTickAsync())
{
     // add your async business logic here
}


Example
Let's write a small console application with two methods having their own PeridicTimer instances, one is configured to tick every minute and another one that ticks every second.

With every tick, increase the counter by one and print it in the console.
static async Task SecondTicker()
{
    PeriodicTimer secondTimer = new PeriodicTimer(new TimeSpan(0, 0, 1));

    while (await secondTimer.WaitForNextTickAsync())
    {
        secs++;
        Console.SetCursorPosition(0, 0);
        Console.Write($"secs: {secs.ToString("00")}");
    }
}


Another one, which sets the second counter to 0 as every minute elapses.
static async Task MinuteTicker()
{
    PeriodicTimer minuteTimer = new PeriodicTimer(new TimeSpan(0, 1, 0));

    while (await minuteTimer.WaitForNextTickAsync())
    {
        mins++;
        secs = 0;
        Console.SetCursorPosition(0, 1);
        Console.Write($"mins: {mins.ToString("00")}");
    }
}


Now let's run them in parallel
static int secs = 0, mins = 0;
static async Task Main(string[] args)
{
    Console.WriteLine("secs: 00");
    Console.WriteLine("mins: 00");

    var secondTicks = SecondTicker();
    var minuteTicks = MinuteTicker();
    await Task.WhenAll(secondTicks, minuteTicks);
}

That way we have two PeridicTimer instances running parallelly without blocking each other and here is the result.

Output

Key Notes

    This timer is intended to be used only by a single consumer at a time
    You can either use the  CancellationToken or call the Dispose() method to interrupt it and cause WaitForNextTickAsync() to return false

HostForLIFE.eu ASP.NET Core Hosting

European best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.