[C#] .Net6新定时器PeriodicTimer

2022-12-01 10:57:57 浏览数 (1)

.NET 中已经有五个其他计时器

  • System.Timers.Timer
  • System.Threading.Timer
  • System.Windows.Forms.Timer
  • System.Web.UI.Timer
  • System.Windows.Threading.DispatcherTimer

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

封装一个定时任务类。

代码语言:javascript复制
public class BackgroundTask{
    private  Task? _timerTask;
    private readonly PeriodicTimer _timer;
    private readonly CancellationTokenSource _cts = new();
    public EventHandler dowork;
    public BackgroundTask(TimeSpan interval)
    {
        _timer = new PeriodicTimer(interval);
    }
    public void Start()
    {
        _timerTask = DoWorkAsync();
    }
    private async Task DoWorkAsync()
    {
        try
        {
            System.Console.WriteLine("开始定时任务");

            while (await  _timer.WaitForNextTickAsync(_cts.Token))
            {

                dowork?.Invoke(null,null);
            }

        }
        catch(OperationCanceledException ex){
            Console.WriteLine(ex.Message);
        }

    }
    public async Task StopAsync()
    {
        if  (_timerTask is null)
        {
            return;
        }
        _cts.Cancel();
        await _timerTask;
        _cts.Dispose();
        System.Console.WriteLine("取消定时任务");
    }
}

测试:

代码语言:javascript复制
XTrace.WriteLine(  "按任意键开始Task");
Console.ReadKey();
var task = new BackgroundTask(TimeSpan.FromMilliseconds(1000));
task.dowork  = (sender,e)=> {
    XTrace.WriteLine("PeriodicTimer 任务。。。");
};
task.Start();
XTrace.WriteLine("按任意键结束Task");
Console.ReadKey();

PeriodicTimer的设计优势,

此 API 仅对重复触发的计时器有意义,触发一次的计时器可能是基于任务的(我们已经为此提供了 Task.Delay)。 计时器将在用户代码执行时暂停,并在结束后恢复下一个时间段。 可以使用提供的取消令牌停止计时器以停止枚举。 不会捕获执行上下文。

0 人点赞