如何在构造函数中使用 PeriodicTimer?
How to use PeriodicTimer inside of constructor?
我想从构造函数启动 .NET 6 中发布的 PeriodicTimer,在这个计时器中我想用异步方法更新数据,我该如何处理它?
您可以创建一个调用此方法的异步方法,并从您想要启动计时器的任何代码中调用它。您可以在构造函数本身中调用该方法并存储任务 returns 而无需等待它:
例如:
class MyClass:IDisposable:IAsyncDisposable
{
PeriodicTimer _timer;
Task _timerTask;
CancellationTokenSource _cts;
public MyClass()
{
_cts=new CancellationTokenSource();
_timer=new PeriodicTimer(TimeSpan.FromSeconds(1));
_timerTask=HandleTimerAsync(_timer,_cts.Token);
}
public void Cancel()=>_cts.Cancel();
async Task HandleTimerAsync(PeriodicTimer timer,CancellationToken cancel=default)
{
try
{
while(await timer.WaitForNextTickAsync(cancel))
{
await Task.Run(()=>SomeHeavyJob(cancel),cancel);
}
}
catch(Exception exc)
{
//Handle the exception but don't propagate it
}
}
public async ValueTask DisposeAsync()
{
_timer.Dispose();
await _timerTask;
GC.SuppressFinalize(this);
}
}
复杂处理的原因是定时器任务在调用PeriodicTimer.Dispose()
后可能不会立即完成。代码将不得不等待它完成。.NET 6 为这种情况引入了 DisposeAsync
。
Dispose
和 DisposeAsync
方法不应抛出异常,这就是处理程序方法使用不传播异常的 catch 块的原因。否则,在处理程序中抛出的任何期望都将在 DisposeAsync
中重新抛出,在这个地方可能无法处理或记录日志,因为其他对象会自行处理。
我想从构造函数启动 .NET 6 中发布的 PeriodicTimer,在这个计时器中我想用异步方法更新数据,我该如何处理它?
您可以创建一个调用此方法的异步方法,并从您想要启动计时器的任何代码中调用它。您可以在构造函数本身中调用该方法并存储任务 returns 而无需等待它:
例如:
class MyClass:IDisposable:IAsyncDisposable
{
PeriodicTimer _timer;
Task _timerTask;
CancellationTokenSource _cts;
public MyClass()
{
_cts=new CancellationTokenSource();
_timer=new PeriodicTimer(TimeSpan.FromSeconds(1));
_timerTask=HandleTimerAsync(_timer,_cts.Token);
}
public void Cancel()=>_cts.Cancel();
async Task HandleTimerAsync(PeriodicTimer timer,CancellationToken cancel=default)
{
try
{
while(await timer.WaitForNextTickAsync(cancel))
{
await Task.Run(()=>SomeHeavyJob(cancel),cancel);
}
}
catch(Exception exc)
{
//Handle the exception but don't propagate it
}
}
public async ValueTask DisposeAsync()
{
_timer.Dispose();
await _timerTask;
GC.SuppressFinalize(this);
}
}
复杂处理的原因是定时器任务在调用PeriodicTimer.Dispose()
后可能不会立即完成。代码将不得不等待它完成。.NET 6 为这种情况引入了 DisposeAsync
。
Dispose
和 DisposeAsync
方法不应抛出异常,这就是处理程序方法使用不传播异常的 catch 块的原因。否则,在处理程序中抛出的任何期望都将在 DisposeAsync
中重新抛出,在这个地方可能无法处理或记录日志,因为其他对象会自行处理。