中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

DotNetCore跨(kua)平(ping)臺~Quartz定時單次任務

回到目錄

之前寫過一篇文件《DotNetCore跨平臺~Quartz熱部署的福音~監控文件夾的變化》,今天主要把框架(jia)優化(hua)了一(yi)下,支持外部觸發(fa),并支持外部將參數以JobDataMap形式進(jin)行(xing)輸入(ru),然后(hou)在(zai)咱(zan)們的Job里(li)進(jin)行(xing)使用它,故稱參數化(hua)任(ren)務(wu)。

Quartz使用場景:

  1. 定時單次任務:在未來某個時間去執行一次
  2. 定點任務  :在某個時間去執行,可以是輪詢的
  3. 周期任務  :按某個時間間隔去輪詢執行

今天說的外部觸(chu)發的任務(wu)是指第一(yi)種,即(ji)(ji)在未來某個時間點(dian)去執(zhi)行(xing),并且只執(zhi)行(xing)一(yi)次(ci)。說一(yi)下思路,這種任務(wu)某個JobBase的子類,它(ta)需(xu)要重寫屬性IsSingle,將值設為1表示(shi)單次(ci)任務(wu),然后在Quartz啟動后,它(ta)會被立即(ji)(ji)執(zhi)行(xing),執(zhi)行(xing)完(wan)成后,銷毀!

用例:你可以在quartz調度(du)(du)中心里對外公開(kai)一(yi)些方法,讓你的(de)(de)Job依賴于某個時間點和(he)參數去執(zhi)行,執(zhi)行一(yi)次就停(ting)止,這樣(yang)我們的(de)(de)調度(du)(du)就更加靈活了。

為單次任務添加了IsSingle屬性(xing)

    [DisallowConcurrentExecution()]
    public abstract class JobBase : ISchedulingJob
    {
        #region Properties

        /// <summary>
        /// 取消資(zi)源
        /// </summary>
        public CancellationTokenSource CancellationSource => new CancellationTokenSource();

        /// <summary>
        /// 執(zhi)行計劃,除了立即執(zhi)行的JOB之(zhi)后,其它(ta)JOB需要實現它(ta)
        /// </summary>
        public virtual string Cron => "* * * * * ?";

        /// <summary>
        /// 是否為(wei)單次任務,黑為(wei)false
        /// </summary>
        public virtual bool IsSingle => false;

        /// <summary>
        /// Job的名稱,默認(ren)為當(dang)前類(lei)名
        /// </summary>
        public virtual string JobName => GetType().Name;

        /// <summary>
        /// Job執行的超時時間(毫秒),默認5分鐘
        /// </summary>
        public virtual int JobTimeout => 5 * 60 * 1000;

        #endregion Properties

        #region Methods

        /// <summary>
        /// Job具體類(lei)去(qu)實現自己的邏輯
        /// </summary>
        protected abstract void ExcuteJob(IJobExecutionContext context, CancellationTokenSource cancellationSource);

        /// <summary>
        /// 當(dang)某(mou)個job超時時,它將被觸發,可以發一(yi)些(xie)通知(zhi)郵件等
        /// </summary>
        /// <param name="arg"></param>
        private void CancelOperation(object arg)
        {
            CancellationSource.Cancel();
            StdSchedulerFactory.GetDefaultScheduler().Result.Interrupt(new JobKey(JobName));
            Console.WriteLine(JobName + "Job執行超(chao)時(shi),已(yi)經取消,等(deng)待下次調度(du)...");
        }

        #endregion Methods

        #region IJob 成員

        public Task Execute(IJobExecutionContext context)
        {
            Timer timer = null;
            try
            {
                timer = new Timer(CancelOperation, null, JobTimeout, Timeout.Infinite);
                Console.WriteLine(DateTime.Now.ToString() + "{0}這個Job開始(shi)執行", context.JobDetail.Key.Name);
                if (context.JobDetail.JobDataMap != null)
                {
                    foreach (var pa in context.JobDetail.JobDataMap)
                        Console.WriteLine($"JobDataMap,key:{pa.Key},value:{pa.Value}");
                }
                ExcuteJob(context, CancellationSource);
            }
            catch (Exception ex)
            {
                Console.WriteLine(this.GetType().Name + "error:" + ex.Message);
            }
            finally
            {
                if (timer != null) timer.Dispose();
            }
            return Task.CompletedTask;
        }

        #endregion
    }

統一的(de)加入Job隊列的(de)方法

在我(wo)們(men)之前的(de)(de)QuartzManager管理者中(zhong),我(wo)們(men)需要添加對單(dan)次任務(wu)的(de)(de)支(zhi)持(chi),這點我(wo)們(men)將任務(wu)加入到(dao)quartz的(de)(de)代碼進行(xing)了重(zhong)構(gou),提取(qu)到(dao)了方法里。

        /// <summary>
        /// 將類型添加到Job隊(dui)列
        /// </summary>
        /// <param name="type">類型</param>
        /// <param name="dt">時間點</param>
        /// <param name="param">參數</param>
        private static void JoinToQuartz(Type type, DateTimeOffset dt, Dictionary<string, object> param = null)
        {
            var obj = Activator.CreateInstance(type);
            if (obj is ISchedulingJob)
            {
                var tmp = obj as ISchedulingJob;
                string cron = tmp.Cron;
                string name = tmp.JobName;
                var cancel = tmp.CancellationSource;

                var jobDetail = JobBuilder.Create(type)
                                          .WithIdentity(name)
                                          .Build();
                if (param != null)
                    foreach (var dic in param)
                        jobDetail.JobDataMap.Add(dic.Key, dic.Value);

                ITrigger jobTrigger;
                if (tmp.IsSingle)
                {
                    jobTrigger = TriggerBuilder.Create()
                                               .WithIdentity(name + "Trigger")
                                               .StartAt(dt)
                                               .Build();
                }
                else
                {
                    jobTrigger = TriggerBuilder.Create()
                                                .WithIdentity(name + "Trigger")
                                                .StartNow()
                                                .WithCronSchedule(cron)
                                                .Build();
                }
                StdSchedulerFactory.GetDefaultScheduler().Result.ScheduleJob(jobDetail, jobTrigger, cancel.Token);
                LoggerInfo($"->任務模塊{name}被裝載...", ConsoleColor.Yellow);
            }
        }

對(dui)外公開的(de)參數化接口(kou)

而對于外界如果希望再次觸發這個單次任務,我們可以在QuartzManager里公開一個方法,用來向當前SchedulerFactory里添加新的(de)Job就可(ke)以了,這個(ge)方(fang)法很簡(jian)單,可(ke)以提供一個(ge)默認(ren)的(de)時間策略(lve),如默認(ren)為1分鐘(zhong)后執行,也可(ke)以自己(ji)控制時間。

      /// <summary>
        /// 任(ren)務在(zai)1分鐘之后被執行1次
        /// </summary>
        /// <param name="type"></param>
        /// <param name="job"></param>
        /// <param name="param"></param>
        public static void SignalJob(Type type, Dictionary<string, object> param)
        {
            SignalJob(type, DateTimeOffset.Now.AddSeconds(10), param);
        }

        /// <summary>
        /// 任(ren)務在某個時間(jian)之后被(bei)執(zhi)行1次
        /// </summary>
        /// <param name="type"></param>
        /// <param name="job"></param>
        /// <param name="offset"></param>
        /// <param name="param"></param>
        public static void SignalJob(Type type, DateTimeOffset offset, Dictionary<string, object> param)
        {
            JoinToQuartz(type, offset);
        }

那么,現在某(mou)個任務調度中心就更加完善了,開發人員在使(shi)用時也很簡(jian)單,只要(yao)繼承JobBase,或者去實(shi)現ISchedulingJob接口就可以了,非(fei)常靈活!

感謝各位的閱讀!

quartz,dotnet core我(wo)們還(huan)在(zai)繼續(xu)研(yan)究的路上!

回到目錄

posted @ 2017-09-15 11:25  張占嶺  閱讀(6137)  評論(5)    收藏  舉報