The first talk about what is Quartz.Net

正如标题所示,文章主要是围绕Quartz.Net作业调度框架话题展开的,内容出自博主学习官方Examples的学习心得与体会,文中难免会有错误之处,还请指出得以指教。

在百度一下搜索Quartz.Net,可以知道Quartz.Net是Net版本的任务调度框架,是一个从java移植过来的Net版本的开源框架,在作业调度方面提供了很好的灵活性而不牺牲简单,能够为执行一个作业而创建简单的或复杂的调度,目前版本支持数据库,集群,插件配置,支持cron表达式等等

Quartz Enterprise Schedulder .Net

官方下载地址:

http://sourceforge.net/projects/quartznet/files/quartznet/

官方文档:

http://www.quartz-scheduler.net/documentation/index.html

到此我们大概了解了一下Quartz.Net是什么,在继续讨论相关Quartz之前,我们先来思考并解决一个问题。

假设程序有这么一个需求,在一定的时间间隔里,轮询做一种操作或者任务,我想首先当然可以这么实现:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            Process();
        }

        public static void Process()
        {
            DateTime now = DateTime.Now;
            //1.0 读取web.config中的定时器的时间间隔
            string timespan = System.Configuration.ConfigurationManager.AppSettings["timer"];
            double dtimespan = 0;
            int repeat = 0;
            if (double.TryParse(timespan, out dtimespan) == false)
            {
                dtimespan = 10;
            }
            Console.WriteLine("Info[{0}]任务初始化完成.....",DateTime.Now);
            while (true)
            {
                try
                {
                    //1.0 开启定时器
                    if ((DateTime.Now - now).TotalSeconds >= dtimespan)
                    {
                        Console.WriteLine("任务正在执行.....这是第{0}次",repeat+1);
                        //开始调度任务
                        SayHello();
                        repeat++;
                        Console.WriteLine("任务执行完成.....");
                        //重置now
                        now = DateTime.Now;
                    }
                    //预留cpu的线程切换时间
                    System.Threading.Thread.Sleep(2000);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error:{0}",ex.ToString());
                }
            }
        }
        public static void SayHello() {
            Console.WriteLine("Info:[{0}] Hello, everyone, I‘m YZR.",DateTime.Now);
        }
    }
}

Test

运行的结果如下:

Info[2016/4/23 星期六 上午 12:01:57]任务初始化完成.....
任务正在执行.....这是第1次
Info:[2016/4/23 星期六 上午 12:02:17] Hello, everyone, I‘m YZR.
任务执行完成.....
任务正在执行.....这是第2次
Info:[2016/4/23 星期六 上午 12:02:37] Hello, everyone, I‘m YZR.
任务执行完成.....
任务正在执行.....这是第3次
Info:[2016/4/23 星期六 上午 12:02:57] Hello, everyone, I‘m YZR.
任务执行完成.....
任务正在执行.....这是第4次
Info:[2016/4/23 星期六 上午 12:03:17] Hello, everyone, I‘m YZR.
任务执行完成.....

上面的程序完成的功能是每20秒会在控制台中打印SayHello的信息,并且会记录任务重复执行的次数。

其实这就是一个简单的任务调度的过程,接下来演示使用Quartz.Net如何实现这个功能:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common.Logging;

namespace Quartz.Examples
{
    public class SayHelloJob : IJob
    {

        private static ILog _log = LogManager.GetLogger(typeof(HelloJob));

        /// <summary>
        /// 作业或者任务需要一个无参构造函数来进行初始化
        /// </summary>
        public SayHelloJob()
        {
        }
        #region IJob 成员

        public void Execute(IJobExecutionContext context)
        {

            _log.Info(string.Format("Hello, everyone, I‘m YZR. - {0}", System.DateTime.Now.ToString("r")));
        }

        #endregion
    }
}

SayHelloJob

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Quartz.Impl;
using Common.Logging;

namespace Quartz.Examples
{
    public class SayHelloExample:IExample
    {
        #region IExample 成员

        public string Name
        {
            get { return GetType().Name; }
        }

        public void Run()
        {
            ILog log = LogManager.GetLogger(typeof(SimpleExample));

            log.Info("------- 初始化中 ----------------------");
            //首先,我们必须得到一个参考的调度程序
            ISchedulerFactory sf = new StdSchedulerFactory();
            IScheduler sched = sf.GetScheduler();

            log.Info("------- 初始化完成 -----------");

            // 得到一个轮询的触发时间
            DateTimeOffset runTime = DateBuilder.EvenMinuteDate(DateTimeOffset.UtcNow);

            log.Info("------- 调度作业  -------------------");

            // 定义一个作业并且绑定到指定的Job类中
            IJobDetail job = JobBuilder.Create<SayHelloJob>()
                .WithIdentity("job1", "group1")
                .Build();

            // 作业的触发器会在下一次轮询的时机中执行作业
            ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity("trigger1", "group1")
                .StartAt(runTime).WithSimpleSchedule(x=>x.WithIntervalInSeconds(20).RepeatForever())
                .Build();

            //根据作业和触发器添加到调度队列
            sched.ScheduleJob(job, trigger);
            log.Info(string.Format("{0} will run at: {1}", job.Key, runTime.ToString("r")));

            //启动调度程序
            sched.Start();
            log.Info("------- 开始调度 -----------------");

            log.Info("------- 等待2分钟.... -------------");

            //睡眠65秒
            Thread.Sleep(TimeSpan.FromSeconds(120));

            // shut down the scheduler
            log.Info("------- 正在关闭调度作业 ---------------------");
            sched.Shutdown(true);
            log.Info("------- 关闭调度作业完成 -----------------");
        }

        #endregion
    }
}

SayHelloExample

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Quartz.Util;
using System.Reflection;

namespace Quartz.Examples
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                //反射得到当前运行程序集
                Assembly asm = Assembly.GetExecutingAssembly();
                //获取所有类
                Type[] types = asm.GetTypes();

                IDictionary<int, Type> typeMap = new Dictionary<int, Type>();
                int counter = 1;

                Console.WriteLine("Select example to run: ");
                List<Type> typeList = new List<Type>();
                //循环遍历当前运行程序集的所有类
                foreach (Type t in types)
                {
                    //将实现了IExample接口的类加入到typeList集合中
                    if (new List<Type>(t.GetInterfaces()).Contains(typeof(IExample)))
                    {
                        typeList.Add(t);
                    }
                }

                typeList.Sort(new TypeNameComparer());

                //循环将序号 类名  加入到typeMap字典中
                foreach (Type t in typeList)
                {
                    string counterString = string.Format("[{0}]", counter).PadRight(4);
                    Console.WriteLine("{0} {1} {2}", counterString, t.Namespace.Substring(t.Namespace.LastIndexOf(".") + 1), t.Name);
                    typeMap.Add(counter++, t);
                }

                Console.WriteLine();
                Console.Write("> ");
                //选择要运行的类的序号
                int num = Convert.ToInt32(Console.ReadLine());
                //获取该类的Type
                Type eType = typeMap[num];
                //得到该类的实例
                IExample example = ObjectUtils.InstantiateType<IExample>(eType);
                //运行Run()
                example.Run();
                Console.WriteLine("Example run successfully.");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error running example: " + ex.Message);
                Console.WriteLine(ex.ToString());

            }
            Console.Read();
        }
        /// <summary>
        /// 用于排序的比较器
        /// </summary>
        public class TypeNameComparer : IComparer<Type>
        {
            public int Compare(Type t1, Type t2)
            {
                if (t1.Namespace.Length > t2.Namespace.Length)
                {
                    return 1;
                }

                if (t1.Namespace.Length < t2.Namespace.Length)
                {
                    return -1;
                }

                return t1.Namespace.CompareTo(t2.Namespace);
            }
        }
    }
}

Main

运行结果如下:

2016-04-23 00:37:43,679 [1] INFO  Quartz.Impl.StdSchedulerFactory.Instantiate(D:
\Quartz.NET-2.3.2\src\Quartz\Impl\StdSchedulerFactory.cs:1021) - Quartz scheduler‘DefaultQuartzScheduler‘ initialized
2016-04-23 00:37:43,681 [1] INFO  Quartz.Impl.StdSchedulerFactory.Instantiate(D:
\Quartz.NET-2.3.2\src\Quartz\Impl\StdSchedulerFactory.cs:1023) - Quartz scheduler version: 2.3.2.0
2016-04-23 00:37:43,683 [1] INFO  Quartz.Examples.SayHelloExample.Run(C:\Users\A
dministrator\Desktop\Quatorz\Quartz.Examples\Quartz.Examples\SayHelloExample.cs:29) - ------- 初始化完成 -----------
2016-04-23 00:37:43,684 [1] INFO  Quartz.Examples.SayHelloExample.Run(C:\Users\A
dministrator\Desktop\Quatorz\Quartz.Examples\Quartz.Examples\SayHelloExample.cs:35) - ------- 调度作业  -------------------
2016-04-23 00:37:43,697 [1] INFO  Quartz.Examples.SayHelloExample.Run(C:\Users\A
dministrator\Desktop\Quatorz\Quartz.Examples\Quartz.Examples\SayHelloExample.cs:50)
- group1.job1 will run at: Fri, 22 Apr 2016 16:38:00 GMT
2016-04-23
00:37:43,697 [1] INFO 
Quartz.Core.QuartzScheduler.Start(D:\Quartz.NET-2.3.2\src\Quartz\Core\QuartzScheduler.cs:441)
- Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.
2016-04-23 00:37:43,697 [1] INFO  Quartz.Examples.SayHelloExample.Run(C:\Users\A
dministrator\Desktop\Quatorz\Quartz.Examples\Quartz.Examples\SayHelloExample.cs:54) - ------- 开始调度 -----------------
2016-04-23 00:37:43,697 [1] INFO  Quartz.Examples.SayHelloExample.Run(C:\Users\A
dministrator\Desktop\Quatorz\Quartz.Examples\Quartz.Examples\SayHelloExample.cs:57) - ------- 等待2分钟.... -------------
2016-04-23
00:38:00,044 [DefaultQuartzScheduler_Worker-1] INFO 
Quartz.Examples.SayHelloJob.Execute(C:\Users\Administrator\Desktop\Quatorz\Quartz.Examples\Quartz.Examples\SayHelloJob.cs:25)

- Hello, everyone, I‘m YZR. - Sat, 23 Apr 2016 00:38:00 GMT
2016-04-23
00:38:20,000 [DefaultQuartzScheduler_Worker-2] INFO 
Quartz.Examples.SayHelloJob.Execute(C:\Users\Administrator\Desktop\Quatorz\Quartz.Examples\Quartz.Examples\SayHelloJob.cs:25)

- Hello, everyone, I‘m YZR. - Sat, 23 Apr 2016 00:38:20 GMT

效果同样也是每20秒运行一次作业,但这只是Quartz.Net框架一个简单的任务调度演示,它拥有着更多复杂有用的功能以及特点,我们在下篇会正式进入Quartz.Net的使用话题。

时间: 2025-01-11 21:24:11

The first talk about what is Quartz.Net的相关文章

quartz入门

quartz有两个重要对象,作业JobDetail和触发器Trigger,它们是多对多的关系 作业 JobDetail JobDetail jobDetail = JobBuilder.newJob(HelloQuartzJob.class) .withIdentity("testJob_1", "group_1") .build(); 触发器 Trigger,Quartz有两大触发器,SimpleTrigger和CronTrigger Trigger trigge

Spring quartz定时任务service注入问题

今天想单元测试一下spring中的quartz定时任务,一顿折腾,到最后总是发现job类里注入的service为null.一开始还以为spring的配置问题,各种找原因,最后还是确定是没有注入. 就去网上搜搜吧.也找出来一些眉目.简单的理解这个原因是job是在quartz中实例化出来的,不受spring的管理.所以就导致注入不进去了.参考这个文章 http://www.tuicool.com/articles/Qjyamu 找着试试的态度,就按照文章里说的.new一个类 public class

Spring中使用Quartz

package com.ncs.hj; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.scheduling.quartz.QuartzJobBean; import java.util.Date; public class SpringQtz { private static int counter = 0; protected

任务调度框架-Quartz.Net

使用Quartz.Net依赖于以下3个组件:Common.Logging.dll.Common.Logging.Core.dll.Quartz.dll 简单封装 1 using Quartz; 2 using Quartz.Impl; 3 using System; 4 using System.Collections.Generic; 5 using System.Linq; 6 using System.Text; 7 using System.Threading.Tasks; 8 9 na

Quartz.NET简介及入门指南

Quartz.NET简介 Quartz.NET是一个功能完备的开源调度系统,从最小的应用到大规模的企业系统皆可适用. Quartz.NET是一个纯净的用C#语言编写的.NET类库,是对非常流行的JAVA开源调度框架 Quartz 的移植. 入门指南 本入门指南包括以下内容: 下载 Quartz.NET 安装 Quartz.NET 根据你的特定项目配置 Quartz 启动一个样例程序 下载和安装 你可以下载 zip 文件或使用 Nuget 程序包.Nuget 程序包只包含 Quartz.NET 运

Quartz.NET 入门,带C#实例

概述 Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等. Quartz.NET允许开发人员根据时间间隔(或天)来调度作业.它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联.整合了 Quartz.NET的应用程序可以重用来自不同事件的作业,还可以为一个事件组合多个作业. 参考 官方学习文档:http://www.quartz-scheduler.net/documentation/index.html 使用实例

分布式调度QUARTZ+SPRING

使用SPRING的定时任务框架,如果是在分布式的环境下,由于有多台节点,会产生相同的任务,会被多个节点执行,这时需引入分布式的QUARTZ. 触发器:存放时间排程 任务:蔟业务代码 排程器:负责调度,即在指定的时间执行对应的任务 如果是分布式QUARTZ,则各个节点会上报任务,存到数据库中,执行时会从数据库中取出触发器来执行,如果触发器的名称和执行时间相同,则只有一个节点去执行此任务. 如果此节点执行失败,则此任务则会被分派到另一节点执行. quartz.properties # =======

quartz 定时

spring3不支持quartz2 1.业务调度的类(就是你想要做的事情的逻辑部门) public class QuartzTest { public void  quartzTest(){ System.out.println("I Love You, zhuzhu"); } } 2.写一个job public class RunJob extends QuartzJobBean{ private QuartzTest quartztest; public QuartzTest ge

java计划任务调度框架quartz结合spring实现调度的配置实例代码分享

点击链接加入群[JavaEE(SSH+IntelliJIDE+Maven)]:http://jq.qq.com/?_wv=1027&k=L2rbHv 一:quartz简介 OpenSymphony 的Quartz提供了一个比较完美的任务调度解决方案. Quartz 是个开源的作业调度框架,定时调度器,为在 Java 应用程序中进行作业调度提供了简单却强大的机制. Quartz中有两个基本概念:作业和触发器.作业是能够调度的可执行任务,触发器提供了对作业的调度 二:quartz spring配置详

定时器(Quartz)快速入门

Quartz概述 Quartz中的触发器 Quartz中提供了两种触发器,分别是CronTrigger和SimpleTrigger. SimpleTrigger 每 隔若干毫秒来触发纳入进度的任务.因此,对于夏令时来说,根本不需要做任何特殊的处理来"保持进度".它只是简单地保持每隔若干毫秒来触发一次,无论你的 SimpleTrigger每隔10秒触发一次还是每隔15分钟触发一次,还是每隔24小时触发一次. CronTrigger 在特定"格林日历"时刻触发纳入进程的