Quartz.NET开源作业调度框架系列(一):快速入门step by step
2015-12-01 08:19
567 查看
Quartz.NET是一个被广泛使用的开源作业调度框架 , 由于是用C#语言创建,可方便的用于winform和asp.net应用程序中。Quartz.NET提供了巨大的灵活性但又兼具简单性。开发人员可用它快捷的创建并执行一个自动化作业。Quartz.NET有很多特征,如:数据库支持,集群,插件,支持cron-like表达式等。
Quartz依赖库为Common.Logging和Common.Logging.Core , 二者需要一并导入 . 然后修改Form1的标题为QuartzDemo.
为了直观的执行定期任务 , 我们添加一个时序图(用Oxyplot控件) , 这里下载并引用Oxyplot.在Form1.cs文件中 ,首先引入需要的命名空间:
重载一个带参数的Form1构造方法:
在Form1的FormClosed事件,即窗体关闭后,将scheduler关闭:
在窗体加载时,创建一个时序图:
定义一个SetMsg方法来更新消息:
注意修改Program.cs中用带参数的Form1构建方法进行实例创建:
值得注意的是,如果用下面的代码格式,必须保证二者的名称完全一致,否则无法实现任务和触发器的绑定.
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文件中 ,首先引入需要的命名空间:
using Quartz; using Quartz.Impl; using Quartz.Job; using System.Threading; using OxyPlot; using OxyPlot.Axes; using OxyPlot.Series;
重载一个带参数的Form1构造方法:
private bool isFirst = true; public Form1(string msg) { InitializeComponent(); _msg = msg; try { //启动 scheduler scheduler.Start(); // 定义一个job并和自定义的HelloJob进行绑定 IJobDetail job = JobBuilder.Create<HelloJob>() .WithIdentity("HelloJob", "SimpleGroup") .Build(); #region Cron Expressions // ITrigger trigger2 = TriggerBuilder.Create() //.WithIdentity("trigger3", "group1") //.WithCronSchedule(" 0 0/5 * * * ?", x => x // .WithMisfireHandlingInstructionFireAndProceed()) //.ForJob("job1", "group1") //.Build(); #endregion //定义一个即时触发的触发器,(每隔1秒进行重复执行) ITrigger trigger= TriggerBuilder.Create() .WithIdentity("trigger1", "SimpleGroup") .StartNow() .WithSimpleSchedule(x => x .WithIntervalInSeconds(1) .RepeatForever()) .Build(); // 将job和trigger进行绑定,并告知 quartz 调度器用trigger去执行job scheduler.ScheduleJob(job, trigger); } catch (SchedulerException se) { Console.WriteLine(se); } }
在Form1的FormClosed事件,即窗体关闭后,将scheduler关闭:
private void Form1_FormClosed(object sender, FormClosedEventArgs e) { //关闭 scheduler scheduler.Shutdown(); }
在窗体加载时,创建一个时序图:
public OxyPlot.WindowsForms.PlotView Plot; private LineSeries lineSeries = new LineSeries { Title = "即时监控(1秒)", StrokeThickness =2 }; private void Form1_Load(object sender, EventArgs e) { Plot = new OxyPlot.WindowsForms.PlotView(); Plot.Model = new PlotModel(); Plot.Dock = DockStyle.Fill; this.panel1.Controls.Add(Plot); Plot.Model.PlotType = PlotType.XY; Plot.Model.Background = OxyColor.FromRgb(255, 255, 255); Plot.Model.TextColor = OxyColor.FromRgb(0, 0, 0); // add Series and Axis to plot model Plot.Model.Series.Add(lineSeries); Plot.Model.Axes.Add(new LinearAxis()); }
定义一个SetMsg方法来更新消息:
private double xInit = 0; public bool SetMsg(string msg) { _msg = msg; //号称NET4最简单的跨进程更新UI的方法 this.Invoke((MethodInvoker)delegate { // runs on UI thread if (isFirst) { this.txtLog.AppendText("Hello to Quartz NET ! Created by JackWang 2015"); isFirst = false; } this.txtLog.AppendText(string.Format("\r\n$JackWang>> You get {0} message from Quartz MyJob...", _msg)); xInit = xInit + 1; lineSeries.Points.Add(new DataPoint(xInit,double.Parse(_msg))); if (lineSeries.Points.Count > 50) { //保留最近50个点 lineSeries.Points.RemoveAt(0); } //更新图表数据 this.Plot.Model.InvalidatePlot(true); }); return true; }
2.3 定义一个HelloJob
在带参数的Form1构造方法中 , 创建的HelloJob的定义为:using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; namespace QuartzDemo { using Quartz; using Quartz.Impl; using Quartz.Job; public class HelloJob : IJob { private static Form1 __instance = null; public void Execute(IJobExecutionContext context) { if (isOpen("Form1")) { //获取当前Form1实例 __instance = (Form1)Application.OpenForms["Form1"]; //随机生成小于100的数 string num = new Random().Next(100).ToString(); //通过方法更新消息 __instance.SetMsg(num); } else { //__instance = new Form1("0"); //__instance.Show(); } } /// <summary> /// 判断窗体是否打开 /// </summary> /// <param name="appName"></param> /// <returns></returns> private bool isOpen(string appName) { FormCollection collection = Application.OpenForms; foreach (Form form in collection) { if (form.Name == appName) { return true; } } return false; } } }
注意修改Program.cs中用带参数的Form1构建方法进行实例创建:
[STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1("0")); }
3 最终效果
最终效果如下 , 每隔1秒,就是用随机的数来更新文本框和图表中的内容:值得注意的是,如果用下面的代码格式,必须保证二者的名称完全一致,否则无法实现任务和触发器的绑定.
相关文章推荐
- java字符串api
- 正则表达式
- 普法知识(14):什么是行贿?
- nginx学习(二)基本配置
- C#_Assembly-Reflection_程序集与反射
- [LeetCode]Smallest Rectangle Enclosing Black Pixels
- iOS-OC-基础-NSDictionary常用方法
- 告诉你Hadoop是什么
- DVWA系列之2 low级别SQL注入
- DVWA系列之2 low级别SQL注入
- oracle怎么查看一个表或一个索引占用多少空间
- http://www.jdon.com/
- ORA-28356: 打开 wallet 的语法无效
- ORA-28368: 无法自动创建 wallet
- ^是什么运算符
- 《UML大战需求分析》-读后感三
- 折半查找的两种写法
- [Nodejs入门]第四篇,用nodejs实现一个爬虫的功能(二)
- linux sort 命令详解
- JSP/Servlet及相关技术详解