.NET 6 新特性 PeriodicTimer
.NET 6 新特性 PeriodicTimer
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);}
}
实现示例如下:
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;}
}
运行输出如下:
More
新的 PeriodicTimer
相比之前的几个 Timer
来说,有下面几个特点
没有 callback 来绑定事件
不会发生重入,只允许有一个消费者,不允许同一个
PeriodicTimer
在不同的地方同时WaitForNextTickAsync
,不需要自己做排他锁来实现不能重入异步化,之前的几个 timer 的 callback 都是同步的,使用新的
timer
我们可以更好的使用异步方法,避免写 Sync over Async 之类的代码Dispose()
之后,该实例就无法再使用,WaitForNextTickAsync
始终返回false
最后来做一个题目,把第一个示例改造一下,最终代码如下:
using var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(30));
using var timer = new PeriodicTimer(TimeSpan.FromSeconds(3));
try
{while (await timer.WaitForNextTickAsync(cts.Token)){await Task.Delay(5000);Console.WriteLine($"Timed event triggered({DateTime.Now:HH:mm:ss})");}
}
catch (OperationCanceledException)
{Console.WriteLine("Operation cancelled");
}
猜一下输出结果是什么,Timed event triggered
会输出几次
References
https://www.ilkayilknur.com/a-new-modern-timer-api-in-dotnet-6-periodictimer
https://docs.microsoft.com/en-us/dotnet/api/system.threading.periodictimer?view=net-6.0
https://github.com/dotnet/runtime/blob/v6.0.0/src/libraries/System.Private.CoreLib/src/System/Threading/PeriodicTimer.cs
https://github.com/dotnet/runtime/issues/31525
https://github.com/WeihanLi/SamplesInPractice/blob/master/net6sample/PeriodicTimerSample/Program.cs
https://github.com/OpenReservation/ReservationServer/blob/dev/OpenReservation.Helper/Services/CronScheduleServiceBase.cs#L91
.NET 6 新特性 PeriodicTimer相关推荐
- 我要学ASP.NET MVC 3.0(一): MVC 3.0 的新特性
摘要 MVC经过其1.0和2.0版本的发展,现在已经到了3.0的领军时代,随着技术的不断改进,MVC也越来越成熟.使开发也变得简洁人性化艺术化. 园子里有很多大鸟都对MVC了如指掌,面对问题犹同孙悟空 ...
- .NET 4.0 Interop新特性ICustomQueryInterface (转载)
.NET 4.0 Interop新特性ICustomQueryInterface 在.NET Framework v4.0发布的新功能中,在名字空间System.Runtime.InteropServ ...
- oracle如何查询虚拟列,Oracle11g新特性之--虚拟列(VirtualColumn)
Oracle 11g新特性之--虚拟列(Virtual Column) Oracle 11G虚拟列Virtual Column介绍 在老的 Oracle 版本,当我们需要使用表达式或者一些计算公式时, ...
- mysql8导入 psc 没有数据_新特性解读 | MySQL 8.0.22 任意格式数据导入
作者:杨涛涛 资深数据库专家,专研 MySQL 十余年.擅长 MySQL.PostgreSQL.MongoDB 等开源数据库相关的备份恢复.SQL 调优.监控运维.高可用架构设计等.目前任职于爱可生, ...
- mysql query browswer_MySQL数据库新特性之存储过程入门教程
MySQL数据库新特性之存储过程入门教程 在MySQL 5中,终于引入了存储过程这一新特性,这将大大增强MYSQL的数据库处理能力.在本文中将指导读者快速掌握MySQL 5的存储过程的基本知识,带领用 ...
- windows无法配置此无线连接_Kubernetes 1.18功能详解:OIDC发现、Windows节点支持,还有哪些新特性值得期待?...
Kubernetes 1.18发布,一些对社区产生影响的新特性日渐完善,如 KSA(Kubernetes Service Account) tokens的OIDC发现和对Windows节点的支持.在A ...
- java字符串去重复_Java 8新特性:字符串去重
本文首发与InfoQ. 8月19日,Oracle发布了JDK 8u20,JDK 8u20包含很多新特性,比如Java编译器更新.支持在运行时通过API来修改MinHeapFreeRatio和MaxHe ...
- Oracle 11g 新特性 -- Transparent Data Encryption (透明数据加密TDE) 增强 说明
一.TransparentData Encryption (TDE:透明数据加密) 说明 Orace TDE 是Orcle 10R2中的一个新特性,其可以用来加密数据文件里的数据,保护从操作系统层面上 ...
- .NET Framework 4.0的新特性
本文将揭示.NET 4.0中的3个新特性:图表控件.SEO支持以及ASP.NET 4可扩展的输出缓存. 图表控件 微软向开发者提供了大量可免费下载的图表控件,可以在.NET 3.5 ASP.NET或W ...
最新文章
- USERADD命令详解
- windows下配置opencv
- Struts2基础知识
- 幼儿园小班上计算机课 作业内容是手口一致,小班幼儿手口不能一致的点数怎么办...
- [vijos1982][NOIP2015]子串
- python----设置默认编码
- Maven——安装(二)
- linux 抓包教程
- SPSS教程——游程检验使用方法,如何验证数据的随机性
- python网课答案查询_网课答案查询助手v1.0
- IMX6 dts 配置GPIO
- 逻辑回归(LR) 算法模型简介
- LeetCode 69. x的平方根
- 原生拦截WebView页面下载链接跳转空白页问题
- java处理脏数据,Java程序的脏数据问题
- python 开发按键钢琴
- 为什么安卓手机没有苹果手机流畅?
- 【解决】Failure to find com.xxx:xxx-target:pom:1.0-SNAPSHOT in https://xxxx/snapshot was cached in the
- python数学建模游戏应用_数学建模在游戏数值策划工作中有哪些应用
- 史上最全Maven教程(四)