Quartz.NET开源作业调度框架系列(一):快速入门step by step-阿里云开发者社区

开发者社区> 开发与运维> 正文
登录阅读全文

Quartz.NET开源作业调度框架系列(一):快速入门step by step

简介: Quartz.NET是一个被广泛使用的开源作业调度框架 , 由于是用C#语言创建,可方便的用于winform和asp.net应用程序中。Quartz.NET提供了巨大的灵活性但又兼具简单性。开发人员可用它快捷的创建并执行一个自动化作业。Quartz.NET有很多特征,如:数据库支持,集群,插件,支持cron-like表达式等。

  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 , 添加好类库后 , 项目文件如下图所示:

1.jpg

 Quartz依赖库为Common.Logging和Common.Logging.Core  ,  二者需要一并导入 . 然后修改Form1的标题为QuartzDemo.

2.2 Form1定制

  在Form1设计视图上 , 为该窗体添加一个TextBox和Panel , 并设置相关属性(背景色,字体等) , 如下图所示:

2.jpg

  为了直观的执行定期任务 , 我们添加一个时序图(用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.jpg

3 最终效果


   最终效果如下 , 每隔1秒,就是用随机的数来更新文本框和图表中的内容:

76497-20151130152030905-1464355915.gif

值得注意的是,如果用下面的代码格式,必须保证二者的名称完全一致,否则无法实现任务和触发器的绑定.

1.png

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章
最新文章
相关文章