【.net core】Web实现定时执行任务


原文参考:https://www.cnblogs.com/osscoder/p/10036062.html

实现方式基于上文,根据自己的实际情况做了配置上的小修改,供同行参考,如有不对的地方欢迎指正

首先是 BaseJobTrigger,在原构造函数中添加了timeType字段用来读取配置文件,适应性更强

/// <summary>
    /// 触发器基类
    /// </summary>
    public abstract class BaseJobTrigger : IHostedService, IDisposable
    {
        //定义Timer线程
        private Timer _timer;
        //定义任务延迟执行的时间
        private readonly TimeSpan _dueTime;  
        //定义任务的间隔触发事件
        private readonly TimeSpan _periodTime;
        //定义任务的具体执行者
        private readonly IJobExecutor _jobExcutor;

        #region  构造函数1
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dueTime">延期执行时间(默认立即执行)</param>
        /// <param name="timer">延迟执行的时间值</param>
        /// <param name="timeType"> 1=FromDays  2=FromHours  3=FromMinutes  4=FromSeconds  5=FromMilliseconds</param>
        /// <param name="jobExcutor">任务执行者</param>
        protected BaseJobTrigger(TimeSpan dueTime,int timeType,int timer,IJobExecutor jobExcutor)
        {
            _dueTime = dueTime;
            _jobExcutor = jobExcutor;

            if (timeType == 1)
                _periodTime = TimeSpan.FromDays(timer);
            else if (timeType == 2)
                _periodTime = TimeSpan.FromHours(timer);
            else if (timeType == 3)
                _periodTime = TimeSpan.FromMinutes(timer);
            else if(timeType == 4)
                _periodTime = TimeSpan.FromSeconds(timer);
            else
                _periodTime = TimeSpan.FromMilliseconds(timer);
        }
        #endregion

        #region  构造函数2
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dueTime">延期执行时间(默认立即执行)</param>
        /// <param name="periodTime">定义任务的间隔触发事件</param>
        /// <param name="jobExcutor">任务执行者</param>
        protected BaseJobTrigger(TimeSpan dueTime, TimeSpan periodTime, IJobExecutor jobExcutor)
        {

            _dueTime = dueTime;
            _periodTime = periodTime;
            _jobExcutor = jobExcutor;
        }
        #endregion

        #region  计时器相关方法

        /// <summary>
        /// 启动TimerTrigger
        /// </summary>
        private void StartTimerTrigger()
        {
            if (_timer == null)
                _timer = new Timer(ExcuteJob, _jobExcutor, _dueTime, _periodTime);
            else
                _timer.Change(_dueTime, _periodTime);
        }

        /// <summary>
        /// 停止TimerTrigger
        /// </summary>
        private void StopTimerTrigger()
        {
            _timer?.Change(Timeout.Infinite, Timeout.Infinite);
        }

        /// <summary>
        /// 具体的Job
        /// </summary>
        /// <param name="obj"></param>
        private void ExcuteJob(object obj)
        {
            try
            {
                var excutor = obj as IJobExecutor;
                excutor?.StartJob();
            }
            catch (Exception e)
            {
                LogUtil.ErrorLog($"执行任务({nameof(GetType)})时出错,信息:{e}");
            }
        }
        #endregion

        #region  系统级任务执行启动
        /// <summary>
        ///  系统级任务执行启动
        /// </summary>
        /// <returns></returns>
        public virtual Task StartAsync(CancellationToken cancellationToken)
        {
            try
            {
                StartTimerTrigger();
            }
            catch (Exception e)
            {
                LogUtil.ErrorLog($"启动定时任务({nameof(GetType)})时出错,信息:{e}");
            }
            return Task.CompletedTask;
        }
        #endregion

        #region 系统级任务执行关闭
        /// <summary>
        ///  系统级任务执行关闭
        /// </summary>
        /// <returns></returns>
        public virtual Task StopAsync(CancellationToken cancellationToken)
        {
            try
            {
                _jobExcutor.StopJob();
                StopTimerTrigger();
            }
            catch (Exception e)
            {
                LogUtil.ErrorLog($"停止定时任务({nameof(GetType)})时出错,信息:{e}");
            }
            return Task.CompletedTask;
        }
        #endregion

        #region 资源释放
        public void Dispose()
        {
            _timer?.Dispose();
        }
        #endregion 
    }
View Code

然后是TimeJobTirgger,继承自基类,负责初始化参数

public class TimeJobTirgger:BaseJobTrigger
    {
        public static int timeType;
        public static int timer;
        public static int delay_start_timer;
        public static string sqlConn;

        /// <summary>
        /// TimeJobTirgger  触发器继承自BaseJobTrigger,在构造函数时传入  任务执行的延迟时间,任务执行的间隔以及具体的任务类
        /// </summary>
        public TimeJobTirgger() : base(TimeSpan.FromMinutes(delay_start_timer), timeType, timer, new TimeJobExcutor(sqlConn))
        {

        }

    }
View Code

下来是TimeJobExcutor,具体负责执行

/// <summary>
    /// 继承自IJobExecutor   是具体执行任务的工作类
    /// </summary>
    public class TimeJobExcutor : IJobExecutor
    {
        //从容器中获取对象
        private readonly BeWXUserApp _app = AutofacExt.GetFromFac<BeWXUserApp>();
        private readonly BeWXMsgApp _msgApp = AutofacExt.GetFromFac<BeWXMsgApp>();
        private readonly AppBasicDataApp _basicApp = AutofacExt.GetFromFac<AppBasicDataApp>();
        private static string _sqlConn;

        public TimeJobExcutor(string sqlConn)
        {
            _sqlConn = sqlConn;
        }

        
        public void StartJob()
        {
            LogUtil.InfoLog("执行任务!");

            //InitDataAndUpdateRemark();  //初始化本地表及完善remark和list信息
            SendMonthMsg();

            //释放资源
            StopJob();
        }

        public void StopJob()
        {
            LogUtil.InfoLog("系统终止任务");
        }
    }
View Code

然后是在StartUp类的ConfigureServices方法中注册服务

//注册定时任务计划(从配置文件获取参数)
            TimeJobTirgger.timeType = int.Parse(Configuration.GetSection("Setting").GetValue<string>("timer_planning_type").ToString());
            TimeJobTirgger.timer = int.Parse(Configuration.GetSection("Setting").GetValue<string>("timer_planning_timer").ToString());
            TimeJobTirgger.delay_start_timer = int.Parse(Configuration.GetSection("Setting").GetValue<string>("delay_start_timer").ToString());
            TimeJobTirgger.sqlConn = Configuration.GetConnectionString("Database").ToString();
            services.AddHostedService<TimeJobTirgger>();
View Code

最后是配置文件

"Setting": {
    "timer_planning_type": "2",
    "timer_planning_timer": "20",
    "delay_start_timer": "20"
  },

为了更好的读取配置文件, 我创建了同名的Setting类,类中的属性和配置文件中保持一致,那么就可以通过以下方式来读取了

Configuration.GetSection("Setting").GetValue<string>("timer_planning_timer").ToString()

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM