首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >托管BackgroundService StopAsync等待后未执行

托管BackgroundService StopAsync等待后未执行
EN

Stack Overflow用户
提问于 2021-01-20 20:44:37
回答 1查看 1.1K关注 0票数 2

下面是从ExecuteAsync继承的MyWorker类的MyWorker方法内部循环的示例代码

代码语言:javascript
复制
 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.DelaystoppingToken被取消之后,使executingTask完成,并且父BackgroundService退出。--我想知道一个绕过这个的方法,以便在返回之前完全执行我的ExecuteAsync。另外一种不包括不将stoppingToken传递给我的延迟方法或类似的方法的方法(这会有效)。

代码语言:javascript
复制
 // 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));
            }

        }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-21 19:14:44

因此,正如@Ralf所建议的那样,问题在于Task.Delay(1000,stoppingToken)抛出了Task.Delay,因此我的代码不再继续。解决方案是捕获给定的异常,而方便的一个队列是将我的Task.Delay封装到Task.WhenAny中,就像这样:受保护的重写异步任务ExecuteAsync(CancellationToken stoppingToken) {

代码语言:javascript
复制
        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()
    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65817388

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档