下面是从ExecuteAsync继承的MyWorker类的MyWorker方法内部循环的示例代码
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested){
// Do some work
// Sleep for 1s
await Task.Delay(1000, stoppingToken);
}
// Do some work after stopping token is canceled
this.WorkThatNeverExecutes()
}问题是,在stoppingToken被取消后,WorkThatNeverExeuctes方法永远不会被执行。
在研究了BackgroundService的源代码之后,我注意到以下几点:在它的StopAsync方法中,它正在等待我自己的后台服务(它的exeutingTask)完成,或者后台服务的cancellationToken被取消(在短暂的延迟之后):
这里发生的事情是我的await Task.Delay在stoppingToken被取消之后,使executingTask完成,并且父BackgroundService退出。--我想知道一个绕过这个的方法,以便在返回之前完全执行我的ExecuteAsync。另外一种不包括不将stoppingToken传递给我的延迟方法或类似的方法的方法(这会有效)。
// Inside BackgroundService.cs
public virtual async Task StopAsync(CancellationToken cancellationToken)
{
// Stop called without start
if (_executingTask == null)
{
return;
}
try
{
// Signal cancellation to the executing method
_stoppingCts.Cancel();
}
finally
{
// Wait until the task completes or the stop token triggers
await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken));
}
}发布于 2021-01-21 19:14:44
因此,正如@Ralf所建议的那样,问题在于Task.Delay(1000,stoppingToken)抛出了Task.Delay,因此我的代码不再继续。解决方案是捕获给定的异常,而方便的一个队列是将我的Task.Delay封装到Task.WhenAny中,就像这样:受保护的重写异步任务ExecuteAsync(CancellationToken stoppingToken) {
while (!stoppingToken.IsCancellationRequested){
// Do some work
// Sleep for 1s
await Task.WhenAny(Task.Delay(1000, stoppingToken));
}
// Do some work after stopping token is canceled
this.ThisWillExecuteAfterStoppingTokenIsCanceled()
}https://stackoverflow.com/questions/65817388
复制相似问题