Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I want to do some async work after Startup.cs is finished. I've implemented some async tasks in a background service by extending 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).

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);
        }
    }
}
like image 834
David Spence Avatar asked Jan 28 '20 13:01

David Spence


People also ask

How do I stop BackgroundService in .NET core?

The BackgroundService token source is cancelled by the StopAsync method. So to cancel the CustomService async work you have to call the StopAsync method. This cancel token provided to the ExecuteAsync method as parameter.

What is IHostedService in .NET core?

Since . NET Core 2.0, the framework provides a new interface named IHostedService helping you to easily implement hosted services. The basic idea is that you can register multiple background tasks (hosted services) that run in the background while your web host or host is running, as shown in the image 6-26.


1 Answers

I didn't quite catch on to the fact that ExecuteAsync is only called once by the framework. 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;
    }
}
like image 195
David Spence Avatar answered Sep 21 '22 12:09

David Spence