C#之quartz任务调度的使用,定时执行任务

1 背景

很多时候,项目需要在不同时刻,执行一个或很多个不同的作业。

Windows执行计划这时并不能很好的满足需求了,迫切需要一个更为强大,方便管理,集群部署的作业调度框架。

2 介绍

Quartz一个开源的作业调度框架,OpenSymphony的开源项目。Quartz.Net 是Quartz的C#移植版本。

它一些很好的特性:

1:支持集群,作业分组,作业远程管理。 

2:自定义精细的时间触发器,使用简单,作业和触发分离。

3:数据库支持,可以寄宿Windows服务,WebSite,winform等。

3 Quartz

3.1 概念解释

   Scheduler     作业调度器。

   IJob             作业接口,继承并实现Execute, 编写执行的具体作业逻辑。

  JobBuilder       根据设置,生成一个详细作业信息(JobDetail)。

  TriggerBuilder   根据规则,生产对应的Trigger

3.2 Nuget安装 

    在Nuget管理器中引入quartz

 PM> Install-Package Quartz

3.3 Quartz的使用步骤

  1. 创建一个ISchedulerFactory,然后并且获取 Scheduler
  2. 启动 Scheduler
  3. 创建 job 任务
  4. 创建 trigger 触发器
  5. 使用触发器规划执行任务( Tell quartz to schedule the job using our trigger)

3.4 实战

示例1 

static void Main(string[] args)
       {
           //从工厂中获取一个调度器实例化
           IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
 
           scheduler.Start();       //开启调度器
 
           //==========例子1(简单使用)===========
 
           IJobDetail job1 = JobBuilder.Create()  //创建一个作业
               .WithIdentity("作业名称", "作业组")
               .Build();
 
           ITrigger trigger1 = TriggerBuilder.Create()
                                       .WithIdentity("触发器名称", "触发器组")
                                       .StartNow()                        //现在开始
                                       .WithSimpleSchedule(x => x         //触发时间,5秒一次。
                                           .WithIntervalInSeconds(5)
                                           .RepeatForever())              //不间断重复执行
                                       .Build();
 
 
           scheduler.ScheduleJob(job1, trigger1);      //把作业,触发器加入调度器。
 
           //==========例子2 (执行时 作业数据传递,时间表达式使用)===========
 
           IJobDetail job2= JobBuilder.Create()
                                       .WithIdentity("myJob", "group1")
                                       .UsingJobData("jobSays", "Hello World!")
                                       .Build();
 
 
           ITrigger trigger2 = TriggerBuilder.Create()
                                       .WithIdentity("mytrigger", "group1")
                                       .StartNow()
                                       .WithCronSchedule("/5 * * ? * *")    //时间表达式,5秒一次     
                                       .Build();
 
 
           scheduler.ScheduleJob(job2, trigger2);     
         
           //scheduler.Shutdown();         //关闭调度器。
       }

声明要执行的作业,HelloJob:

/// 
   /// 作业
   /// 
   public class HelloJob : IJob
   {
       public void Execute(IJobExecutionContext context)
       {
           Console.WriteLine("作业执行!");
       }
   }

声明要执行的作业,DumbJob:

public class DumbJob : IJob
    {
        /// 
        ///  context 可以获取当前Job的各种状态。
        /// 
        /// 
        public void Execute(IJobExecutionContext context)
        {
 
            JobDataMap dataMap = context.JobDetail.JobDataMap;
 
            string content = dataMap.GetString("jobSays");
 
            Console.WriteLine("作业执行,jobSays:" + content);
        }
    }

示例2

Global.asax

using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;

namespace SOP
{
    public class Global : System.Web.HttpApplication
    {
        //调度器
        IScheduler scheduler;
        //调度器工厂
        ISchedulerFactory factory;

        protected void Application_Start(object sender, EventArgs e)
        {
            //1、创建一个调度器
            factory = new StdSchedulerFactory();
            scheduler = factory.GetScheduler();
            scheduler.Start(); //开启任务调度

            //2、创建一个任务
            IJobDetail job = JobBuilder.Create().WithIdentity("job1", "group1").Build();

            //3、创建一个触发器
            //DateTimeOffset runTime = DateBuilder.EvenMinuteDate(DateTimeOffset.UtcNow);
            ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity("trigger1", "group1")
                .WithCronSchedule("0 30 8 * * ?")     //每天上午8:30触发
                //.StartAt(runTime)
                .Build();

            //4、将任务与触发器添加到调度器中
            scheduler.ScheduleJob(job, trigger);
            
            //scheduler.Shutdown();         //关闭调度器。
        }

        protected void Session_Start(object sender, EventArgs e)
        {

        }

        protected void Application_BeginRequest(object sender, EventArgs e)
        {

        }

        protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {

        }

        protected void Application_Error(object sender, EventArgs e)
        {

        }

        protected void Session_End(object sender, EventArgs e)
        {

        }

        protected void Application_End(object sender, EventArgs e)
        {
            //   在应用程序关闭时运行的代码
            if (scheduler != null)
            {
                scheduler.Shutdown(true);
            }
        }
    }
}

SecurityThreatTimeJob.cs

using Quartz;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using hpwin;
using System.Collections;

namespace SOP
{
    /// 
    /// 时间截止通知
    /// 
    public class SecurityThreatTimeJob : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            string sqlSelect = "select * from aqyhgl_yhsb where sjjztz = '2' and zt > '13' and zt < '29' ";
            DateTime dTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));//当前时间
            DataTable dtSelect = SQLHelper.getDataTable(sqlSelect);

            if (dtSelect.Rows.Count > 0)
            {
                for(int i = 0; i < dtSelect.Rows.Count; i++)  //遍历表中的每一条记录
                {
                    DateTime yjwcsj = Convert.ToDateTime(dtSelect.Rows[i]["yjwcsj"].ToString()); //获取预计完成时间
                    string jdrId = dtSelect.Rows[i]["jdrId"].ToString(); //获取接单人ID
                    string qx = dtSelect.Rows[i]["qx"].ToString(); //获取责任部门去向编号
                    string bh = dtSelect.Rows[i]["bh"].ToString(); //获取编号

                    TimeSpan span = yjwcsj - dTime;  //两个时间相减,得到一个 时间间隔 TimeSpan 实例

                    if (span.TotalDays < 3)   // 7天前
                    {
                        //获取通知人:领导审核人
                        DataTable dtDepartment = SQLHelper.getDataTable("select * from aqyhgl_dp where bh = '" + qx + "'");
                        string ldshrsIds = ""; //领导审核人
                        if (dtDepartment.Rows.Count > 0)
                        {
                            string ldshrs = dtDepartment.Rows[0]["ldshrs"].ToString();
                            string[] arrShrs = ldshrs.Split(',');
                            foreach (string arrShr in arrShrs)
                            {
                                string id = arrShr.Split('|')[0];
                                ldshrsIds += (ldshrsIds == "" ? "" : ",") + id;
                            }
                        }
                        //通知人包括:接单人和领导审核人
                        string tzrIds = ""; //通知人ID

                        if (!string.IsNullOrEmpty(jdrId))
                            tzrIds = jdrId;

                        if (!string.IsNullOrEmpty(ldshrsIds))
                            tzrIds += (tzrIds == "" ? "" : ",") + ldshrsIds;


                        //发送消息
                        if (!string.IsNullOrEmpty(tzrIds))
                        {
                            //消息通知
                            DataTable udt = hpwinbasic.getUsers(tzrIds);
                            string stitle = "[安全隐患到期提醒通知]";//定义标题
                            string saffairid = bh;//定义处理id
                            string pdesc = DateTime.Now.ToString("yyyy - MM - dd HH: mm: ss") + " " + "【" + dtSelect.Rows[i]["yhmc"].ToString() + "】" + "预计完成时间为:" + yjwcsj + ",请尽快处理!";//内容
                            string linkurl = "http://pt.hpwin.com/sites/market/clients.html?m=1";//定义链接
                            Messages.MSG_Add(jdrId, udt, "A1011", saffairid, stitle, pdesc, linkurl, true);//发送消息


                            //更新表中的时间截止通知字段:“1":“已通知”,"2":"未通知"
                            string upSql = " update aqyhgl_yhsb set sjjztz = '1' where bh = '" + bh + "'";
                            ArrayList sqlList = new ArrayList();
                            sqlList.Add(upSql);
                            SQLHelper.ExecuteNonQuery(sqlList);
                        }

                    }

                }

                   

            }


        }
    }
}

4 参考

Quartz.Net官方2.X教程  http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/index.html

Quartz.Net开源地址   https://github.com/quartznet/quartznet

https://blog.csdn.net/u011966339/article/details/79565831

https://www.cnblogs.com/Vincent-yuan/p/10867277.html

 

 

你可能感兴趣的:(C#)