I'm trying manually stop the class that inherit from BackgroundService
.
ExampleService.cs
public class ExampleService : BackgroundService, IExampleService
{
private readonly ILogger<ExampleService> _logger;
private bool stopRequested { get; set; }
public ExampleService(ILogger<ExampleService> logger)
{
_logger = logger;
}
public async Task Stoping(CancellationToken token)
{
_logger.LogInformation("Stoping");
stopRequested = true;
await StopAsync(token);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var count = 0;
while (!stoppingToken.IsCancellationRequested && !stopRequested)
{
await Task.Delay(1000, stoppingToken);
_logger.LogInformation("Service is working {0}", count++);
}
}
}
public interface IExampleService
{
Task Stoping(CancellationToken token = default);
}
Call from API
[HttpGet("stoptask2")]
public async Task<IActionResult> Get()
{
await exampleService.Stoping();
return Ok();
}
But the service doesn't stop. I know IHostApplicationLifetime
is working but all application is stopping. I don't want this.
I have tried How to cancel manually a BackgroundService in ASP.net core but it doesn't work.
I know I should stop the service using stoppingToken in ExecuteAsync, but how?
Without seeing the actual registration I can only guess, but I think problem is the registration - AddHostedService
creates one service descriptor and when you register IExampleService
it will create another unrelated one, so you have two different instances of service. Personally I would just use the separation of concerns principle and introduce separate service like IStopper
which would have two methods Stop
and IStopped
(or expose a cancelation toke instead of the second one), but if you want to keep your current class/interface structure - then be sure to provide registration which will result in only one instance:
builder.Services.AddSingleton<ExampleService>(); // singleton
builder.Services.AddSingleton<IExampleService>(s => s.GetRequiredService<ExampleService>()); // reabstract as interface
builder.Services.AddHostedService<ExampleService>(s => s.GetRequiredService<ExampleService>()); // reabstract as hosted service