asp.net core 动态增加定时任务

最近写一个接口对接平台, 为了灵活和减少代码开发工作量.
需要做成可配置的.
可配置就意味着动态性, 代码不是写死的.
大致把接口形式分为了两种, 一种是主动的, 一种是被动的.
主动的接口是指: 由 我方 系统主动发起调用 对方 的webapi
被动的接口是指: 由 对方 系统主动发起调用 我方 的webapi

本文主要讲的是主动接口, 主动类型的接口多数是由定时器触发的.
那么, 这种类型的接口.在asp.net core 中如何实现呢?
方案不止一种.
一种方案是第三方的Quartz.Net
另外一种方案是 自己用 Microsoft.Extensions.Hosting.IHostedService 加Timer 自己写一个简单的定时器. 而且是长期循环执行的这种.
考虑到简单灵活,满足要求就够的 编程风格. 还是打算自己弄一个.

当然这篇文章里不牵扯到具体的持久化, 这个需要按照自己的项目需求去配置.
关于 IHostedService 和 BackgroundService 需要自己百度一下. 相关说明.
其实还算简单的.主要是两个类

BackgroundServicesHelper.cs

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Linq;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;

namespace WSI.BackgroundServices
{
    public static class BackgroundServicesHelper
    {
        /// <summary>
        /// 反射取得所有的业务逻辑类
        /// </summary>
        private static Type[] GetAllChildClass( Type baseType)
        {
              var types = AppDomain.CurrentDomain.GetAssemblies()
                //取得实现了某个接口的类
                //.SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(ISecurity))))  .ToArray();
                //取得继承了某个类的所有子类
              .SelectMany(a => a.GetTypes().Where(t => t.BaseType == baseType))
              .ToArray();

            return types;
        }
         

        public static Type[] GetAllBackgroundService( )
        {
            return GetAllChildClass(typeof(BackgroundService));
        }

        /// <summary>
        /// 自动增加后台任务.所有继承自BackgroundService的类都会自动运行
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddBackgroundServices(this IServiceCollection services)
        {
            //services.AddHostedService<TimedService>(); //asp.net core 应该是这个.
            //或者  单为方便循环自动创建, 所以改成使用AddTransient 也一样可以使用.
            //services.AddTransient<IHostedService, TimedService>();  
            //services.AddTransient(typeof(Microsoft.Extensions.Hosting.IHostedService),backtype);
            //var backtypes = BackgroundServicesHelper.GetAllBackgroundService();
            //foreach (var backtype in backtypes)
            //{
            //    services.AddTransient(typeof(Microsoft.Extensions.Hosting.IHostedService),backtype);
            //}

            var backtypes = GetAllBackgroundService();
            foreach (var backtype in backtypes)
            {
                services.AddTransient(typeof(Microsoft.Extensions.Hosting.IHostedService), backtype);
            }
            return services;
        }
         

    }
}

再创建一个具体干活的服务类. 这个类是用来执行具体任务的.
TimedService.cs

using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace WSI.BackgroundServices
{

    /// <summary>
    /// 定时任务触发器
    /// </summary>
    public class TimedService : BackgroundService
    {
        /**
         *  
            需要在Startup.cs 里面注册
         *  public void ConfigureServices(IServiceCollection services)
            { 
                services.AddHostedService<TimedService>();
                或者
                services.AddTransient<IHostedService, TimedService>();
            }
         * */

        private readonly ILogger _logger;
        //private Timer _timer;

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

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            _logger.LogInformation("servers startA"); 
            while (!stoppingToken.IsCancellationRequested)
            {
                //执行任务
                _logger.LogInformation("TimedServiceA DoWork");
                await Task.Delay(5000, stoppingToken); //延迟暂停5秒
            }
            _logger.LogInformation("servers end");
        }
 
        public override void Dispose()
        {
            base.Dispose(); 
        }
         
    }
}

还可以写更多个
TimedServiceA,
TimedServiceB,
只要继承自BackgroundService 就可以了.

最后 使用的时候还需要在
startup.cs
中增加一行

        public void ConfigureServices(IServiceCollection services)
        {
            ..........
            //自动注入定时器开始,//后台任务启动专用.   
            services.AddBackgroundServices();
            //自动注入定时器结束,
            ..........
       }

本篇文章主要重点是 AddBackgroundServices() 里面的动态创建 Services的方法

这一行.
services.AddTransient(typeof(Microsoft.Extensions.Hosting.IHostedService), backtype);

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值