简体   繁体   English

如何使用取消令牌停止范围服务?

[英]How to stop scoped service using Cancellation Token?

I am looking for a way to stop the Scoped background service using a Cancellation Token .我正在寻找一种使用Cancellation Token来停止Scoped background service的方法。 I followed the following steps:我按照以下步骤操作:

ScopedAlertingService.cs 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 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我正在使用IServiceCollection运行此服务

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

I am using the following code to stop the service after 30 seconds:我正在使用以下代码在 30 秒后停止服务:

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

But the debugger is not going to stopAsync method of ConsumeScopedServiceHostedService .但是调试器不会停止ConsumeScopedServiceHostedServicestopAsync方法。 What am I doing wrong here?我在这里做错了什么? Thanks谢谢

You can inject IHostedService as Singleton then you can call stop method on back ground service.您可以将IHostedService注入为Singleton然后您可以在后台服务上调用停止方法。

Updated: In hosted service the stopasync only called when application shutdown but in your code you can use this and it works:更新:在托管服务中,stopasync 仅在应用程序关闭时调用,但在您的代码中,您可以使用它并且它可以工作:

 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);
                }
            }
    }

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

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