lon*_*nix 19 c# async-await asp.net-core asp.net-core-hosted-services asp.net-core-5.0
后台服务的ASP.NET Core文档显示了许多实现示例。
有一个在计时器上启动服务的示例,尽管它是同步的。还有另一个异步示例,用于启动具有范围依赖项的服务。
我需要同时执行这两项操作:每 5 分钟启动一个服务,并且它具有范围内的依赖项。没有这样的例子。
我结合了这两个示例,但我不确定使用Timer
async 的安全方法TimerCallback
。
例如
public class MyScheduler : IHostedService
{
private Timer? _timer;
private readonly IServiceScopeFactory _serviceScopeFactory;
public MyScheduler(IServiceScopeFactory serviceScopeFactory) => _serviceScopeFactory = serviceScopeFactory;
public void Dispose() => _timer?.Dispose();
public Task StartAsync(CancellationToken cancellationToken)
{
_timer = new Timer((object? state) => {
using var scope = _serviceScopeFactory.CreateScope();
var myService = scope.ServiceProvider.GetRequiredService<IMyService>();
await myService.Execute(cancellationToken); // <------ problem
}), null, TimeSpan.Zero, TimeSpan.FromSeconds(5));
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken) {
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
}
Run Code Online (Sandbox Code Playgroud)
计时器需要同步回调,所以问题是await
. 调用异步服务的安全方法是什么?
Art*_*tur 39
使用BackgroundService
而不是IHostedService
public class MyScheduler : BackgroundService
{
private readonly IServiceScopeFactory _serviceScopeFactory;
public MyScheduler(IServiceScopeFactory serviceScopeFactory) => _serviceScopeFactory = serviceScopeFactory;
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// Option 1
while (!stoppingToken.IsCancellationRequested)
{
// do async work
using (var scope = _serviceScopeFactory.CreateScope())
{
var myService = scope.ServiceProvider.GetRequiredService<IMyService>();
await myService.Execute(stoppingToken);
}
await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken);
}
// Option 2 (.NET 6)
using var timer = new PeriodicTimer(TimeSpan.FromMinutes(5));
while (await timer.WaitForNextTickAsync(stoppingToken))
{
// do async work
// ...as above
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
17883 次 |
最近记录: |