ASP.NET Core的文档为后台服务提供了许多实现示例。其中有一个例子是使用定时器启动服务,但它是同步的。还有另一个例子是异步的,用于使用作用域依赖项启动服务。
我需要同时满足这两种需求:每5分钟启动一次服务,并且需要使用作用域依赖项。但是没有对应的示例。我结合了两个示例,但不确定如何安全地使用异步
例如:
我需要同时满足这两种需求:每5分钟启动一次服务,并且需要使用作用域依赖项。但是没有对应的示例。我结合了两个示例,但不确定如何安全地使用异步
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;
}
}
计时器需要一个同步回调函数,所以问题在于await
。有没有一种安全的方法来调用异步服务?
计时器需要一个同步回调函数,所以问题在于await
。有没有一种安全的方法来调用异步服务?
ThreadPool
长期饱和,因为越来越多的线程可能会在计时器滴答声响起时被阻塞。 - Theodor ZouliasTimer
,该计时器在ThreadPool
上调用事件处理程序。 - Theodor ZouliasPeriodicTimer
是一个可等待计时器,而不是基于事件的计时器。 - Theodor Zoulias