Quartz.NET開源作業調度框架系列(一):快速入門step by step


  Quartz.NET是一個被廣泛使用的開源作業調度框架 , 由於是用C#語言創建,可方便的用於winform和asp.net應用程序中。Quartz.NET提供了巨大的靈活性但又兼具簡單性。開發人員可用它快捷的創建並執行一個自動化作業。Quartz.NET有很多特征,如:數據庫支持,集群,插件,支持cron-like表達式等。

1 為什么選擇Quartz.NET

      在大部分的應用中,都需要對數據庫進行定期備份 , 這個備份任務可以是每天晚上12:00或者每周星期二晚上12:00,或許僅僅每個月的最后一天執行。如果應用程序中需要這樣的自動化執行任務 , 那么建議使用Quartz.NET調度器作為框架,為我們提供基礎服務。 Quartz.NET允許開發人員根據時間間隔(或天)來調度作業 , 它實現了作業和觸發器的多對多關系,還能把多個作業與不同的觸發器關聯。整合了 Quartz.NET的應用程序可以重用來自不同事件的作業,還可以為一個事件組合多個作業.

2 如何創建一個簡單的Quartz.NET

2.1 創建桌面應用程序並添加類庫

  用VS2012創建一個QuartzDemo的桌面應用程序 , 並用NuGet程序包管理添加Quartz.NET , 添加好類庫后 , 項目文件如下圖所示:

   Quartz依賴庫為Common.Logging和Common.Logging.Core  ,  二者需要一並導入 . 然后修改Form1的標題為QuartzDemo.

2.2 Form1定制

  在Form1設計視圖上 , 為該窗體添加一個TextBox和Panel , 並設置相關屬性(背景色,字體等) , 如下圖所示:

  為了直觀的執行定期任務 , 我們添加一個時序圖(用Oxyplot控件) , 這里下載並引用Oxyplot.在Form1.cs文件中  ,首先引入需要的命名空間:

1     using Quartz; 2     using Quartz.Impl; 3     using Quartz.Job; 4     using System.Threading; 5 
6     using OxyPlot; 7     using OxyPlot.Axes; 8     using OxyPlot.Series;

  重載一個帶參數的Form1構造方法:

 1         private bool isFirst = true;  2         public Form1(string msg)  3  {  4  InitializeComponent();  5             _msg = msg;  6             try
 7  {  8                 //啟動 scheduler
 9  scheduler.Start(); 10                 // 定義一個job並和自定義的HelloJob進行綁定
11                 IJobDetail job = JobBuilder.Create<HelloJob>() 12                     .WithIdentity("HelloJob", "SimpleGroup") 13  .Build(); 14                 #region Cron Expressions
15                // ITrigger trigger2 = TriggerBuilder.Create() 16                //.WithIdentity("trigger3", "group1") 17                //.WithCronSchedule(" 0 0/5 * * * ?", x => x 18                // .WithMisfireHandlingInstructionFireAndProceed()) 19                //.ForJob("job1", "group1") 20                //.Build();
21                 #endregion
22 
23                 //定義一個即時觸發的觸發器,(每隔1秒進行重復執行)
24                 ITrigger trigger= TriggerBuilder.Create() 25                     .WithIdentity("trigger1", "SimpleGroup") 26  .StartNow() 27                     .WithSimpleSchedule(x => x 28                         .WithIntervalInSeconds(1) 29  .RepeatForever()) 30  .Build(); 31                 // 將job和trigger進行綁定,並告知 quartz 調度器用trigger去執行job 
32  scheduler.ScheduleJob(job, trigger); 33  } 34             catch (SchedulerException se) 35  { 36  Console.WriteLine(se); 37  } 38        
39         }

  在Form1的FormClosed事件,即窗體關閉后,將scheduler關閉:

1         private void Form1_FormClosed(object sender, FormClosedEventArgs e) 2  { 3             //關閉 scheduler
4  scheduler.Shutdown(); 5         }

   在窗體加載時,創建一個時序圖:

 1         public OxyPlot.WindowsForms.PlotView Plot;  2         private LineSeries lineSeries = new LineSeries { Title = "即時監控(1秒)", StrokeThickness =2 };  3         private void Form1_Load(object sender, EventArgs e)  4  {  5             Plot = new OxyPlot.WindowsForms.PlotView();  6             Plot.Model = new PlotModel();  7             Plot.Dock = DockStyle.Fill;  8             this.panel1.Controls.Add(Plot);  9 
10             Plot.Model.PlotType = PlotType.XY; 11             Plot.Model.Background = OxyColor.FromRgb(255, 255, 255); 12             Plot.Model.TextColor = OxyColor.FromRgb(0, 0, 0); 13             
14             // add Series and Axis to plot model
15  Plot.Model.Series.Add(lineSeries); 16             Plot.Model.Axes.Add(new LinearAxis()); 17         }

  定義一個SetMsg方法來更新消息:

 1         private double xInit = 0;  2         public bool SetMsg(string msg)  3  {  4             _msg = msg;  5             //號稱NET4最簡單的跨進程更新UI的方法
 6             this.Invoke((MethodInvoker)delegate
 7  {  8                 // runs on UI thread
 9                 if (isFirst) 10  { 11                     this.txtLog.AppendText("Hello to Quartz NET ! Created by JackWang 2015"); 12                     isFirst = false; 13  } 14                 this.txtLog.AppendText(string.Format("\r\n$JackWang>> You get {0} message from Quartz MyJob...", _msg)); 15                 xInit = xInit + 1; 16                 lineSeries.Points.Add(new DataPoint(xInit,double.Parse(_msg))); 17                 if (lineSeries.Points.Count > 50) 18  { 19                     //保留最近50個點
20                     lineSeries.Points.RemoveAt(0); 21  } 22                  //更新圖表數據
23                 this.Plot.Model.InvalidatePlot(true); 24                
25  }); 26             return true; 27 
28         }

2.3 定義一個HelloJob

  在帶參數的Form1構造方法中 , 創建的HelloJob的定義為:

 1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Text;  5 using System.Windows.Forms;  6 namespace QuartzDemo  7 {  8     using Quartz;  9     using Quartz.Impl; 10     using Quartz.Job; 11     public  class HelloJob : IJob 12  { 13         private static Form1 __instance = null; 14         public  void Execute(IJobExecutionContext context) 15  { 16           
17             if (isOpen("Form1")) 18  { 19                 //獲取當前Form1實例
20                 __instance = (Form1)Application.OpenForms["Form1"]; 21                 //隨機生成小於100的數
22                 string num = new Random().Next(100).ToString(); 23                 //通過方法更新消息
24  __instance.SetMsg(num); 25  } 26             else
27  { 28                 //__instance = new Form1("0"); 29                 //__instance.Show();
30               
31  } 32         
33  } 34         /// <summary>
35         /// 判斷窗體是否打開 36         /// </summary>
37         /// <param name="appName"></param>
38         /// <returns></returns>
39         private  bool isOpen(string appName) 40  { 41             FormCollection collection = Application.OpenForms; 42             foreach (Form form in collection) 43  { 44                 if (form.Name == appName) 45  { 46                     return true; 47  } 48  } 49             return false; 50  } 51  } 52 }

  注意修改Program.cs中用帶參數的Form1構建方法進行實例創建:

1  [STAThread] 2         static void Main() 3  { 4  Application.EnableVisualStyles(); 5             Application.SetCompatibleTextRenderingDefault(false); 6             Application.Run(new Form1("0")); 7         }

3 最終效果

   最終效果如下 , 每隔1秒,就是用隨機的數來更新文本框和圖表中的內容:

  值得注意的是,如果用下面的代碼格式,必須保證二者的名稱完全一致,否則無法實現任務和觸發器的綁定.

 


免責聲明!

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



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