简体   繁体   中英

How to stop scoped service using Cancellation Token?

I am looking for a way to stop the Scoped background service using a Cancellation Token . I followed the following steps:

ScopedAlertingService.cs

namespace BackgroundTasksSample.Services
{
    internal interface IScopedAlertingService
    {
        Task DoWork(System.Threading.CancellationToken stoppingToken);
    }
    public class ScopedAlertingService : IScopedAlertingService
    {
        private int executionCount = 0;
        private readonly ILogger _logger;

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

        public async Task DoWork(System.Threading.CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                executionCount++;
                _logger.LogInformation(
                    "Alert: Scoped Processing Service is working. Count: {Count}", executionCount);
            }
        }
    }
}

ConsumedServiceHostedService.cs

namespace BackgroundTasksSample.Services
{
    public class ConsumeScopedServiceHostedService : BackgroundService
    {
        private readonly ILogger<ConsumeScopedServiceHostedService> _logger;

        public ConsumeScopedServiceHostedService(IServiceProvider services,
            ILogger<ConsumeScopedServiceHostedService> logger)
        {
            Services = services;
            _logger = logger;
        }

        public IServiceProvider Services { get; }


        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            CancellationTokenSource _stoppingCts = CancellationTokenSource.CreateLinkedTokenSource(stoppingToken);
            _stoppingCts.CancelAfter(30000);

            _logger.LogInformation(
                "Consume Scoped Service Hosted Service running.");

            while (!stoppingToken.IsCancellationRequested)
            {
                await Task.Delay(10000, stoppingToken);

                using (var scope = Services.CreateScope())
                {
                    var scopedProcessingService =
                        scope.ServiceProvider
                            .GetRequiredService<IScopedAlertingService>();

                    
                    await scopedProcessingService.DoWork(stoppingToken);
                }
            }
    }

        private async Task DoWork(CancellationToken stoppingToken)
        {
            _logger.LogInformation(
                "Consume Scoped Service Hosted Service is working.");

            using (var scope = Services.CreateScope())
            {
                var scopedProcessingService =
                    scope.ServiceProvider
                        .GetRequiredService<IScopedAlertingService>();

                await scopedProcessingService.DoWork(stoppingToken);
            }
        }

        public override async Task StopAsync(CancellationToken stoppingToken)
        {
            _logger.LogInformation(
                "Consume Scoped Service Hosted Service is stopping.");

            await Task.CompletedTask;
        }
    }
    }

I am running this service using IServiceCollection

#region snippet2
services.AddHostedService<ConsumeScopedServiceHostedService>();
services.AddScoped<IScopedAlertingService, ScopedAlertingService>();
#endregion

I am using the following code to stop the service after 30 seconds:

 CancellationTokenSource _stoppingCts = CancellationTokenSource.CreateLinkedTokenSource(stoppingToken);
 _stoppingCts.CancelAfter(30000); 

But the debugger is not going to stopAsync method of ConsumeScopedServiceHostedService . What am I doing wrong here? Thanks

You can inject IHostedService as Singleton then you can call stop method on back ground service.

Updated: In hosted service the stopasync only called when application shutdown but in your code you can use this and it works:

 protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            CancellationTokenSource _stoppingCts = CancellationTokenSource.CreateLinkedTokenSource(stoppingToken);
            _stoppingCts.CancelAfter(30000);

            _logger.LogInformation(
                "Consume Scoped Service Hosted Service running.");

            while (!_stoppingCts.Token.IsCancellationRequested)
            {
                await Task.Delay(10000, _stoppingCts.Token);

                using (var scope = Services.CreateScope())
                {
                    var scopedProcessingService =
                        scope.ServiceProvider
                            .GetRequiredService<IScopedAlertingService>();

                    
                    await scopedProcessingService.DoWork(_stoppingCts.Token);
                }
            }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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