Intro
.NET 6 中引入了一个新的 Timer ——
System.Threading.PeriodicTimer , 和之前的几个 Timer 相比一个最大的区别就是 , 新的 PeriodicTimer 的事件处理可以比较方便地使用异步方式 , 消除了使用 callback 的机制 , 减少了使用的复杂度 。
Sample
来看一个使用示例:
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($"Timed event triggered({DateTime.Now:HH:mm:ss})"); }}catch (OperationCanceledException){ Console.WriteLine("Operation cancelled");}通常 PeriodicTimer 可以结合 CancellationToken 一起使用 , 和 CancellationToken 一起用的时候需要注意 , 如果 cancellationToken 被取消的时候会抛出一个
OperationCanceledException 需要考虑自己处理异常
除此之外如果 PeriodicTimer 被 Dispose , 这个 timer 就相当于是失效的 , 并且无法重新恢复 , 来看下面这个示例:
var timer1 = new PeriodicTimer(TimeSpan.FromSeconds(2));timer1.Dispose();if (await timer1.WaitForNextTickAsync()){ Console.WriteLine("Timer1 event triggered");}上面这样的一段代码 , 在 WaitForNextTickAsync 之前就已经调用了 Dispose() , 此时 WaitForNextTickAsync 方法会始终返回 false , 所以 Console.WriteLine 的逻辑也不会被执行
我们之前会尝试使用 Timer 来做一些后台任务 , 可以改造成使用新的 PeriodicTimer 来实现 , 小示例如下:
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); }}
推荐阅读
- 2021年男工人退休年龄最新规定是什么?
- 哪种桔子皮做陈皮最好,新鲜桔子皮怎么做陈皮
- 信阳毛尖的特点,女性喝信阳毛尖的好处
- 头围的测量方法
- 发型|五一发型别乱剪,新女发18款送给大家,想不美都难
- 新生儿黄疸可以喝水吗
- 如何判断新生儿不舒服
- 新生儿黄疸最晚多久退
- 新生儿吃奶老是吐奶怎么回事
- .net6给winform带来的新功能
