.Netcore BackgroundService结合时间表达式(Corn)使用

一、引入时间表达式组件

NCrontab

二、实现代码

    /// 
    /// 后台调度服务
    /// 
    public abstract class TestBackgroundService : BackgroundService
    {
        private CrontabSchedule _schedule;
        private DateTime _nextRun;

        /// 
        /// "0/10 * * * * *"
        /// 
        protected abstract string Schedule { get; set; }

        /// 
        /// 变更调度,有值的情况会覆盖Schedule
        /// 
        protected virtual string ChangeSchedule { get; set; }

        /// 
        /// 服务提供器
        /// 
        public IServiceProvider ServiceProvider { get; set; }

        /// 
        /// 构造函数
        /// 
        /// 
        public TestBackgroundService(IServiceProvider serviceProvider)
        {
            ServiceProvider = serviceProvider;
        }

        /// 
        /// 具体业务执行代码
        /// 
        /// 
        protected abstract Task Process(IServiceProvider serviceProvider);

        /// 
        /// 异步执行
        /// 
        /// 任务取消
        /// 
        /// 
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            if (string.IsNullOrEmpty(Schedule))
            {
                using (var scope = ServiceProvider.CreateScope())
                {
                    await Process(scope.ServiceProvider);
                }
            }

            #region 初始化

            var key = $"{AppDomain.CurrentDomain.FriendlyName}.{GetType().Name}";
            _schedule = CrontabSchedule.Parse(Schedule, new CrontabSchedule.ParseOptions
            {
                IncludingSeconds = true
            });
            _nextRun = _schedule.GetNextOccurrence(DateTime.Now);

            #endregion
            do
            {
                try
                {
                    var now = DateTime.Now;
                    if (now >= _nextRun)
                    {
                        await ExecProcess();
                    }
                }
                catch (Exception e)
                {
                    Logger.LogError(e, $"{key}执行异常");
                }

                await Task.Delay(1000, stoppingToken); //1 seconds delay
            } while (!stoppingToken.IsCancellationRequested);

            await Task.CompletedTask;
        }


        private async Task ExecProcess()
        {
            using (var scope = ServiceProvider.CreateScope())
            {
                await Process(scope.ServiceProvider);
            }

            //覆盖调度
            if (!string.IsNullOrEmpty(ChangeSchedule) && ChangeSchedule != Schedule)
            {
                Schedule = ChangeSchedule;
                _schedule = CrontabSchedule.Parse(Schedule, new CrontabSchedule.ParseOptions { IncludingSeconds = true });
            }
            _nextRun = _schedule.GetNextOccurrence(DateTime.Now);
        }

        #region Logger

        /// 
        /// 
        /// 
        protected ILogger Logger => LazyLogger.Value;

        /// 
        /// 日志工厂
        /// 
        public ILoggerFactory LoggerFactory => ServiceProvider.GetRequiredService();

        private Lazy LazyLogger =>
            new Lazy(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true);

        #endregion
    }

三、调用

// 继承父类:TestBackgoundService

public class NewTestBackgoundService:TestBackgoundService
{

}

// 依赖注入
service.AddBackgroundService();

你可能感兴趣的:(.netcore,java,前端)