等待后托管的 BackgroundService StopAsync 未执行
Hosted BackgroundService StopAsync not executing after await
这是 MyWorker
class 的 ExecuteAsync 方法中的循环示例代码,它继承自 BackgroundService
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
传递给我的 Delay 方法或类似方法(这会起作用)。
// 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));
}
}
正如@Ralf 所建议的那样,问题是 Task.Delay(1000, stoppingToken) 抛出
TaskCanceledException 所以我的代码没有继续。解决方案是捕获给定的异常,方便的一种方式是像这样将我的 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()
}
这是 MyWorker
class 的 ExecuteAsync 方法中的循环示例代码,它继承自 BackgroundService
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
传递给我的 Delay 方法或类似方法(这会起作用)。
// 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));
}
}
正如@Ralf 所建议的那样,问题是 Task.Delay(1000, stoppingToken) 抛出 TaskCanceledException 所以我的代码没有继续。解决方案是捕获给定的异常,方便的一种方式是像这样将我的 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()
}