我是靠谱客的博主 欣喜彩虹,最近开发中收集的这篇文章主要介绍.NET 6新东西--PeriodicTimer,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在.NET 6中引入了新Timer:System.Threading.PeriodicTimer,它和之前的Timer相比,最大的区别就是新的PeriodicTimer事件处理可以方便地使用异步,消除使用callback机制减少使用复杂度。讲解PeriodicTimer之前我们先来看以下该怎么使用它:

using var cts = new CancellationTokenSource();
Console.CancelKeyPress += (sender, e) =>
{
    e.Cancel = true;
    cts.Cancel();
};

using var timer = new PeriodicTimer(TimeSpan.FromSeconds(3));
try
{
    while (await timer.WaitForNextTickAsync(cts.Token))
    {
        Console.WriteLine($"触发事件({DateTime.Now:HH:mm:ss})");
    }
}
catch (OperationCanceledException e)
{
    Console.WriteLine("出现异常,运行停止"+e.Message);
}

一般来说PeriodicTimer会结合CancellationToken来使用,需要注意的是当CancellationToken被取消时会抛出OperationCanceledException异常,因此需要手动处理异常。另外当PeriodicTimer被Dispose掉时,这个timer就失效且无法恢复,我们来看下面这个示例:

var timer1 = new PeriodicTimer(TimeSpan.FromSeconds(10));
timer1.Dispose();
if (await timer1.WaitForNextTickAsync())
{
    Console.WriteLine("事件执行");
}

上面的代码中在WaitForNextTickAsync之前就已经调用了Dispose(),这时WaitForNextTickAsync方法就只能返回false,因此后续的代码将不会被执行。在以前的.NET版本中我们会使用Timer来做后台任务,那么在.NET6中我们同样可以这么做,官方示例代码如下:

public abstract class TimerScheduledService : BackgroundService
{
    private readonly PeriodicTimer _timer;
    private readonly TimeSpan _period;
    protected readonly ILogger Logger;
    protected TimerScheduledService(TimeSpan period, ILogger logger)
    {
        Logger = logger;
        _period = period;
        _timer = new PeriodicTimer(_period);
    }
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        try
        {
            while (await _timer.WaitForNextTickAsync(stoppingToken))
            {
                try
                {
                    Logger.LogInformation("Begin execute service");
                    await ExecuteInternal(stoppingToken);
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex, "Execute exception");
                }
                finally
                {
                    Logger.LogInformation("Execute finished");
                }
            }
        }
        catch (OperationCanceledException operationCancelledException)
        {
            Logger.LogWarning(operationCancelledException, "service stopped");
        }
    }
    protected abstract Task ExecuteInternal(CancellationToken stoppingToken);
    public override Task StopAsync(CancellationToken cancellationToken)
    {
        Logger.LogInformation("Service is stopping.");
        _timer.Dispose();
        return base.StopAsync(cancellationToken);
    }
}

public class TimedHealthCheckService : TimerScheduledService
{
    public TimedHealthCheckService(ILogger<TimedHealthCheckService> logger) : base(TimeSpan.FromSeconds(5), logger)
    {
    }
    protected override Task ExecuteInternal(CancellationToken stoppingToken)
    {
        Logger.LogInformation("Executing...");
        return Task.CompletedTask;
    }
}

总结

PeriodicTimer相比之前的Timer来说,有下面几个特点:

  1. 没有callback来绑定事件;
  2. 不会发生重入,只允许有一个消费者,不允许同一个PeriodicTimer在不同的地方同时WaitForNextTickAsync,不需要自己做排他锁来实现不能重入;
  3. 异步化。之前的timer的callback都是同步的,使用新timer可以使用异步方法,避免了编写Sync over Async代码;
  4. Dispose之后,实例就无法使用,并且WaitForNextTickAsync始终返回false。

最后

以上就是欣喜彩虹为你收集整理的.NET 6新东西--PeriodicTimer的全部内容,希望文章能够帮你解决.NET 6新东西--PeriodicTimer所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部