【.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