星期五, 3月 25, 2022

[C#] Quartz.NET

公司內部有使用 Quartz.NET 來排程管理,了解並簡易筆記基礎用法,該筆記為 Quartz.NET 3.3.3 版本

常見三個功能,分別為 Job、Trigger 和 Scheduler
  • Job 必須實作 IJob Interface,只有一個 Execute 方法
  • Trigger:設定 Job 被執行的時間、頻率,有 SimpleTrigger 和 CronTrigger 兩種
  • Scheduler:對應 Job 和 Trigger,基本上大多以 StdSchedulerFactory 為主

Job:單純輸出時間,該 Job 有套用  DisallowConcurrentExecutionAttribute,下面為官方說明
An attribute that marks a IJob class as one that must not have multiple instances executed concurrently (where instance is based-upon a IJobDetail definition - or in other words based upon a JobKey).
簡單說就是一次只能建立一個 Job 出來跑就是啦,單純筆記該重點,不會有明顯效果可以觀察喔
using Quartz;
using System;
using System.Threading.Tasks;

namespace QuartzSample
{
    [DisallowConcurrentExecution]
    public class HelloQuartzJob : IJob
    {
        public Task Execute(IJobExecutionContext context)
        {
            return Task.Run(() =>
            {
                Console.WriteLine($"Hello Quartz.Net - {DateTime.Now}");
            });
        }
    }
}
Job:參數傳遞,紀錄兩種參數傳遞方式
using Quartz;
using System;
using System.Threading.Tasks;

namespace QuartzSample
{
    public class SayHelloJob : IJob
    {
        // 參數直接注入 UserName
        public string UserName { get; set; }

        public Task Execute(IJobExecutionContext context)
        {
            // 透過 context 抓取參數
            JobKey key = context.JobDetail.Key;
            JobDataMap dataMap = context.JobDetail.JobDataMap;
            string UserNameFromContext = dataMap.GetString("UserNameFromContext");

            return Task.Run(() =>
            {
                Console.WriteLine($"兩位好:{UserName} - {UserNameFromContext} - {DateTime.Now}");
            });
        }
    }
}
Quartz.NET 執行 Code
using Quartz;
using Quartz.Impl;
using System;
using System.Threading.Tasks;

namespace QuartzSample
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            // 取得 Scheduler 並啟動
            StdSchedulerFactory factory = new StdSchedulerFactory();
            IScheduler scheduler = await factory.GetScheduler();
            // 假如 Scheduler 沒有啟動的話,Trigger 是不會開始動的喔
            await scheduler.Start();

            // 定義 Job 
            IJobDetail job = JobBuilder.Create<HelloQuartzJob>()
                .Build();

            IJobDetail job2 = JobBuilder.Create<SayHelloJob>()
                .UsingJobData(nameof(SayHelloJob.UserName), "Terry")
                .UsingJobData("UserNameFromContext", "Vivian")
                .Build();

            // 定義 Trigger
            ITrigger trigger = TriggerBuilder.Create()
                .StartNow()
                .WithSimpleSchedule(x => x
                    .WithIntervalInSeconds(1) // 每一秒觸發一次
                    .RepeatForever())
                .Build();

            ITrigger trigger2 = TriggerBuilder.Create()
                .StartNow()
                .WithSimpleSchedule(x => x
                    .WithIntervalInSeconds(3) // 每三秒觸發一次
                    .RepeatForever())
                .Build();

            // 對應 Job 和 Trigger
            await scheduler.ScheduleJob(job, trigger);
            await scheduler.ScheduleJob(job2, trigger2);

            // Main Thread 結束後,全部的 Worker Thread 就結束了,會看不到輸出結果,
            // 所以故意在這邊停止 10 秒
            await Task.Delay(TimeSpan.FromSeconds(10));
        }
    }
}

沒有留言:

張貼留言