使用Quartz.net實現的任務調度


一、介紹

 Quartz.net是Quartz的.net版本,主要用途是用來管理定時需要執行的任務,和數據庫的job有點類似,他管理的任務包括但不限於數據,還可以包括類似於發送郵件,短信等任務,更可以查看任務狀態,總而言之,是一個強大,開源且輕量級的任務調度框架。

官網:http://www.quartz-scheduler.net/

在園子里其實已經有很多人已經寫過Quartz.net的相關文章了,在研究Quartz.net的過程中也借鑒了很多他們的相關經驗,並將一些想法記錄下來,以供以后參考。

二、簡單的Job

  [DisallowConcurrentExecutionAttribute]
    public class HelloJob: IJob
    {
        public Task Execute(IJobExecutionContext context)
        {
            Console.WriteLine("Info From HelloJob");
            Thread.Sleep(30000);
            LogHelper.WriteInfo("Info From HelloJob");
            return Task.FromResult(0);
        }
    }

普通的job繼承IJob就可以,上面的代碼是像系統中寫日志,在控制台調用如下。

static void Main(string[] args)
        {
            //創建一個作業調度池
            ISchedulerFactory schedf = new StdSchedulerFactory();
            IScheduler sched = schedf.GetScheduler();
            //創建出一個具體的作業
            IJobDetail job = JobBuilder.Create<HelloJob>().Build();           
            //配置一個觸發器
            ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithSimpleSchedule(x=>x.WithIntervalInSeconds(3).WithRepeatCount(int.MaxValue)).Build();
            //加入作業調度池中
            sched.ScheduleJob(job, trigger);
            //開始運行
            sched.Start();
            Console.ReadKey();
        }

其中調度器就是一個管理者,他管理着他控制范圍內的所有的job的開始,暫停等信息。具體的作業,也就是上面的Job,這個Job會和一個觸發器相關聯,這個觸發器用來控制Job的觸發事件,觸發次數等,在Quartz.net中有兩種觸發器類型,一種是簡單觸發器,也就是上面的ISimpleTrigger接口,還有一種是Cron類型的觸發器,對應的接口名是ICronTrigger,他使用cron表達式來描述Job的觸發事件,不了解cron表達式的可以百度具體代表的意思,這里就不詳述了。

三、持久化job到本地

上面的代碼只是Quartz的簡單使用,但是不能可視化的控制調度池內的job。上面說到Quartz.net很強大,要想做到這一點也很簡單,將job持久化到本地,將調度器,job詳情,相關觸發器的信息都抽象成數據存儲在數據庫中就行了。

quartz.net的github內提供了多種數據庫的建表腳本,大家可以根據自己的需要去取,地址是:https://github.com/quartznet/quartznet/tree/master/database/tables,我用的是sqlServer版本的,只需要改一下數據庫的名稱就行。

表建好之后需要在程序中初始化相關配置,初始化的代碼如下:

        public async static Task<IScheduler> GetScheduler()
        {
            try
            {
                if (scheduler == null)
                {
                    #region quartz 實例配置 還包括集群,線程池等配置,可單獨放到config文件中配置
                    var properties = new NameValueCollection();
                    //存儲類型
                    properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz";
                    properties["quartz.serializer.type"] = "binary";
                    //表明前綴
                    properties["quartz.jobStore.tablePrefix"] = "QRTZ_";
                    //驅動類型
                    properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz";
                    //數據源名稱
                    properties["quartz.jobStore.dataSource"] = "Quartz";
                    //連接字符串
                    properties["quartz.dataSource.Quartz.connectionString"] = ConfigurationManager.AppSettings["quartzConnect"];
                    //sqlserver版本
                    properties["quartz.dataSource.Quartz.provider"] = "SqlServer";
                    //最大鏈接數
                    properties["quartz.dataSource.Quartz.maxConnections"] = "5";
                    #endregion

                    ISchedulerFactory sf = new StdSchedulerFactory(properties);
                    scheduler =await sf.GetScheduler();

                    LogHelper.WriteInfo(ConfigurationManager.AppSettings["quartzConnect"].ToString());
                    LogHelper.WriteInfo("任務調度初始化成功");
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteError("任務調度初始化失敗!", ex);
            }
            return scheduler;
        }

由於我從NuGet應用的Quartz是3.0.7.0版本的,方法都是異步的,所以都寫成了異步方法(c#的異步還沒怎么理解透徹,寫法可能有誤,請諒解)。這些配置因為版本經常會更新,所以不同的時期可能會有所不同,大家可以百度最新的配置。配置完成之后就可以調用該方法獲取最新的調度器,然后對調度器內的Job進行控制了,詳細的代碼會文末會給出GitHub的地址,有需要的可以去GitHub上clone。

Job能夠持久化了,如果代碼只能點擊exe文件運行,那持久化就沒什么意義了,所以我選擇使用Topshelf來創建一個服務,作為服務端來一直運行,服務啟動時就初始化調度器。調用的代碼如下:

static void Main(string[] args)
        {
            FileInfo fi = new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "Web.config");
            XmlConfigurator.ConfigureAndWatch(fi);
            LogHelper.SetConfig(fi);
            HostFactory.Run(config => 
            {
                config.Service<QuartzHelper>(setting =>
                {
                    setting.ConstructUsing(name => new QuartzHelper());
                    setting.WhenStarted( tc =>  tc.start());
                    setting.WhenStopped( tc =>  tc.StopSchedule());
                });
                config.RunAsLocalSystem();

                config.SetDescription("Quartz初使用");
                config.SetDisplayName("QuartzService");
                config.SetServiceName("QuartzService");
            });
        }

四、管理Job

持久化完成之后,就需要寫個管理端來管理Job了,在這里我選擇使用傳統的MVC建一個管理端,為了圖方便,我使用了曉道的管理端框架,頁面如下:

這里的Job就是上面的HelloJob,需要說明一下的是,在新增的時候,類名需要和Job的名稱保持一致,因為在代碼中需要通過類名字段來反射找到dll文件中的Job,比如這里的類名我填的就是HelloJob,前面的命名空間不需要填。添加完成之后啟動使用Topshelf創建的服務:

服務啟動完成之后就可以看到記錄的日志了:

 

 五、末尾

要想更加深入了解Quartz.net的同學,可以看看張善友大神的系列文章

代碼已經上傳到GitHub上了,GitHub的地址為:https://github.com/cpf121/Quartz.net-Demo 。代碼拉下來后運行方式如下:

1.去GitHub取到最新的建表腳本,自己建表,並修改config文件中的連接語句

2.命令提示符使用管理員權限找到QuartzService文件夾下的QuartzService.exe文件,運行QuartzService.exe Install

3.在管理端添加對應的Job信息。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM