如何在构造函数中使用 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

DisposeDisposeAsync 方法不应抛出异常,这就是处理程序方法使用不传播异常的 catch 块的原因。否则,在处理程序中抛出的任何期望都将在 DisposeAsync 中重新抛出,在这个地方可能无法处理或记录日志,因为其他对象会自行处理。