.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机制减少使用复杂度。
封装一个定时任务类。
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("取消定时任务");
}
}
测试:
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)。 计时器将在用户代码执行时暂停,并在结束后恢复下一个时间段。 可以使用提供的取消令牌停止计时器以停止枚举。 不会捕获执行上下文。