ASP.NET Core之托管服务

在 ASP.NET Core 中,后台任务作为托管服务实现.托管服务是一个类,而且必须实现 IHostedService 接口,该接口定义了两个方法:

  1. StartAsync(CancellationToken cancellationToken)
    该方法包含启动后台任务的逻辑,当启动服务器并触发 IApplicationLifetime.ApplicationStarted
    后调用该方法.
  2. StopAsync(CancellationToken
    cancellationToken)主机正常关闭时触发,包含结束后台任务和处理任何非托管资源的逻辑.如果应用意外关闭,则可能不会调用.

托管服务在应用启动时激活一次,在应用关闭时正常关闭.实现 IDisposable 时,可在处置服务容器时处理资源.如果在执行后台任务期间引发错误,即使未调用 StopAsync ,也应调用 Dispose.

计时的后台任务

public class TimedHostedService : IHostedService, IDisposable
    {

        private readonly ILogger _logger;
        private Timer _timer;
        public TimedHostedService(ILogger<TimedHostedService> logger)
        {
            _logger = logger;
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Timed Background Service is starting." + DateTime.Now);
            _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(5));//立即执行一次,每5秒执行一次
            return Task.CompletedTask;
        }


        private void DoWork(object state)
        {
            _logger.LogInformation("Timed Background Service is working." + DateTime.Now);
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Timed Background Service is stopping." + DateTime.Now);
            _timer?.Change(Timeout.Infinite, 0);//不再执行
            return Task.CompletedTask;
        }


        public void Dispose()
        {
            _timer?.Dispose();
        }
    }

复制代码

注册该后台任务:

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddHostedService<TimedHostedService>();
        }

其实官方帮我们封装了一个类来简化上述代码:

  /// <summary>
  /// Base class for implementing a long running <see cref="T:Microsoft.Extensions.Hosting.IHostedService" />.
  /// </summary>
  public abstract class BackgroundService : IHostedService, IDisposable

因此上述代码可以修改成:

public class MyBackGroundTask : BackgroundService
    {
        private readonly ILogger _logger;

        private Timer _timer;

        public MyBackGroundTask(ILogger<MyBackGroundTask> logger)
        {
            _logger = logger;
        }
        
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            _logger.LogInformation($" MyBackGroundTask is starting. {DateTime.Now}");
            while (!stoppingToken.IsCancellationRequested)
            {
                _logger.LogInformation($" MyBackGroundTask is working. {DateTime.Now}");
                await Task.Delay(5000, stoppingToken);
            }
            _logger.LogInformation($" MyBackGroundTask is stopping. {DateTime.Now}");
        }
    }

示例二:在后台任务中使用有作用域的服务

要使用有作用域的服务,需要先创建一个作用域.默认情况下,不会为托管服务创建作用域.

public interface IScopedProcessingService
    {
        void DoWork();
    }

    public class ScopedProcessingService : IScopedProcessingService
    {
        private readonly ILogger _logger;
        public ScopedProcessingService(ILogger<ScopedProcessingService> logger)
        {
            _logger = logger;
        }
        public void DoWork()
        {
            _logger.LogInformation($"Scoped Processing Service is working. {DateTime.Now}");
        }
    }
public class ConsumeScopedServiceHostedService : IHostedService
    {

        private readonly ILogger _logger;

        public IServiceProvider Services { get; }

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

        public Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation($"Consume Scoped Service Hosted Service is starting. {DateTime.Now}");
            DoWork();
            return Task.CompletedTask;
        }

        private void DoWork()
        {
            _logger.LogInformation($"Consume Scoped Service Hosted Service is working. {DateTime.Now}");
            using (IServiceScope scope = Services.CreateScope())//创建一个作用域.
            {
                IScopedProcessingService scopedProcessingService = scope.ServiceProvider.GetRequiredService<IScopedProcessingService>();
                scopedProcessingService.DoWork();
            }
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation($"Consume Scoped Service Hosted Service is stopping. {DateTime.Now}");
            return Task.CompletedTask;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

栀梦星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值