1

我正在尝试实现托管服务,但我想知道在通话中我应该对 CancellationToken 做什么IHostedService.StartAsync

Microsoft 文档中有很多关于取消令牌StopAsync本质上是超时(默认为 5 秒),这意味着正常关闭应该在合理的时间范围内发生。

但关于 中的令牌StartAsync,并没有太多信息。如果有的话,文档指定实现不应该等待长时间运行的初始化过程,而应该只返回一个长时间运行的任务。因此,如果我支持取消,我是否应该将取消令牌传递给创建该长时间运行任务的任何对象?如果是,取消这个令牌不是更笨的版本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);
    }
}
4

1 回答 1

4

CancellationToken传入的可StartAsync用于确定是否应取消启动过程,但据我了解,您已经知道了。这是写在这里

表示启动过程已中止。

如果查看where StartAsyncis called,您可以看到CancellationToken传入StartAsync函数的 which 与IHostApplicationLifetime.ApplicationStopping. 据我了解,如果应用程序关闭得太早以至于并非所有托管服务都已完全启动,则仅使用此令牌。但是,我不知道如果StopAsync触发了起始令牌是否会被调用(我必须在源代码中进一步挖掘或在文档中搜索更多内容)。

总结一下: -method 中
CancellationTokeninStartAsync应该只传递给StartAsync支持取消的任何调用方法。如果请求的关闭发生得太早以至于托管服务尚未完全启动,它将允许应用程序正常关闭。

于 2019-12-04T17:41:49.950 回答