【发布时间】:2019-12-04 15:41:59
【问题描述】:
我正在尝试实现托管服务,但我想知道在 IHostedService.StartAsync 调用中我应该如何处理 CancellationToken。
Microsoft documentation 中有很多关于 StopAsync 中的取消令牌本质上是超时(默认为 5 秒),这意味着应该在合理的时间范围内发生正常关闭。
但是关于StartAsync中的token,信息不多。如果有的话,文档指定实现不应该等待长时间运行的初始化过程,而应该只返回一个长时间运行的任务。
因此,如果我支持取消,我是否应该将取消令牌传递给创建该长时间运行任务的任何对象?如果是,取消这个令牌不是更笨的StopAsync 版本吗?为什么框架会这样做?
事实上,在微软自己的抽象 BackgroundService 中,StartAsync 的实现实际上完全忽略了该令牌并创建了一个新令牌将在调用 StopAsync 时被取消...
所以我认为框架传递的初始令牌的全部意义实际上是用于阻塞
通过覆盖虚拟BackgroundService.StartAsync 方法来初始化过程(尽管文档建议反对它)?例如
public class MyBackgroundService : BackgroundService
{
public override Task StartAsync(CancellationToken cancellationToken)
{
// Block the thread for initialisation with cancellation (replace Task.Delay by actual initialisation)
Task.Delay(TimeSpan.FromSeconds(10), cancellationToken).GetAwaiter().GetResult();
// Start the long running task proper
return base.StartAsync(cancellationToken);
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
// some long running process (write some actual background running code here)
return Task.Factory.StartNew(_ => {while(!stoppingToken.IsCancellationRequested){}}, null, stoppingToken);
}
}
【问题讨论】:
-
这可能不是由于取消的特定用途。一般规则是每个异步方法都应该有一个取消令牌参数。因此,如果将来需要令牌,这不是重大更改。
标签: c# async-await asp.net-core-hosted-services