简体   繁体   English

如何手动取消 .NET 核心 IHostedService 后台任务?

[英]How can I manually cancel a .NET core IHostedService background task?

I want to do some async work after Startup.cs is finished.我想在 Startup.cs 完成后做一些异步工作。 I've implemented some async tasks in a background service by extending BackgroundService .我通过扩展BackgroundService在后台服务中实现了一些异步任务。

My question is how to cancel the task from running at a time when I determine?我的问题是如何在我确定的时间取消任务运行? I can only see examples in the documentation for delaying the next cycle.我只能在文档中看到延迟下一个周期的示例。

I've tried to manually execute StopAsync but the while loop executes forever (the token is not cancelled, even though I feel like it should be, because I've passed the token to StopAsync and the implementation looks like that's what it's meant to do).我尝试手动执行StopAsync但 while 循环永远执行(令牌没有被取消,即使我觉得应该取消,因为我已将令牌传递给StopAsync并且实现看起来就是它的意思)。

Here is some simplified code:下面是一些简化的代码:

public class MyBackgroundService : BackgroundService
{
    private readonly ILogger<MyBackgroundService> _logger;

    public MyBackgroundService(ILogger<MyBackgroundService> logger)
    {
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("MyBackgroundService is starting.");

        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("MyBackgroundService task doing background work.");

            var success = await DoOperation();
            if (!success)
            {
                // Try again in 5 seconds
                await Task.Delay(5000, stoppingToken);
                continue;
            }

            await StopAsync(stoppingToken);
        }
    }
}

I didn't quite catch on to the fact that ExecuteAsync is only called once by the framework.我不太明白ExecuteAsync只被框架调用一次的事实。 So the answer is simply to break out of the loop when you're done.因此,答案很简单,完成后跳出循环。

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    _logger.LogInformation("MyBackgroundService is starting.");

    while (!stoppingToken.IsCancellationRequested)
    {
        _logger.LogInformation("MyBackgroundService task doing background work.");

        var success = await DoOperation();
        if (!success)
        {
            // Try again in 5 seconds
            await Task.Delay(5000, stoppingToken);
            continue;
        }

        break;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM