zoukankan      html  css  js  c++  java
  • 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
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Quartz.Examples
    {
        /// <summary>
        /// Interface for examples.
        /// </summary>
        /// <author>Marko Lahma (.NET)</author>
        public interface IExample
        {
            string Name
            {
                get;
            }
    
            void Run();
        }
    }
    IExample.cs

    运行结果如下:

    2016-04-23 00:37:43,679 [1] INFO  Quartz.Impl.StdSchedulerFactory.Instantiate(D:
    Quartz.NET-2.3.2srcQuartzImplStdSchedulerFactory.cs:1021) - Quartz scheduler'DefaultQuartzScheduler' initialized
    2016-04-23 00:37:43,681 [1] INFO  Quartz.Impl.StdSchedulerFactory.Instantiate(D:
    Quartz.NET-2.3.2srcQuartzImplStdSchedulerFactory.cs:1023) - Quartz scheduler version: 2.3.2.0
    2016-04-23 00:37:43,683 [1] INFO  Quartz.Examples.SayHelloExample.Run(C:UsersA
    dministratorDesktopQuatorzQuartz.ExamplesQuartz.ExamplesSayHelloExample.cs:29) - ------- 初始化完成 -----------
    2016-04-23 00:37:43,684 [1] INFO  Quartz.Examples.SayHelloExample.Run(C:UsersA
    dministratorDesktopQuatorzQuartz.ExamplesQuartz.ExamplesSayHelloExample.cs:35) - ------- 调度作业  -------------------
    2016-04-23 00:37:43,697 [1] INFO  Quartz.Examples.SayHelloExample.Run(C:UsersA
    dministratorDesktopQuatorzQuartz.ExamplesQuartz.ExamplesSayHelloExample.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.2srcQuartzCoreQuartzScheduler.cs:441) - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.
    2016-04-23 00:37:43,697 [1] INFO  Quartz.Examples.SayHelloExample.Run(C:UsersA
    dministratorDesktopQuatorzQuartz.ExamplesQuartz.ExamplesSayHelloExample.cs:54) - ------- 开始调度 -----------------
    2016-04-23 00:37:43,697 [1] INFO  Quartz.Examples.SayHelloExample.Run(C:UsersA
    dministratorDesktopQuatorzQuartz.ExamplesQuartz.ExamplesSayHelloExample.cs:57) - ------- 等待2分钟.... -------------
    2016-04-23 00:38:00,044 [DefaultQuartzScheduler_Worker-1] INFO  Quartz.Examples.SayHelloJob.Execute(C:UsersAdministratorDesktopQuatorzQuartz.ExamplesQuartz.ExamplesSayHelloJob.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:UsersAdministratorDesktopQuatorzQuartz.ExamplesQuartz.ExamplesSayHelloJob.cs:25)

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

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

  • 相关阅读:
    禁止后台运行
    图标的圆角和光晕效果和启动画面
    IOS 开发 有关iPhone程序的安装目录UUID 唯一标识
    NSOperation与performSelectorOnMainThread
    Java web开发学习规划
    JAVA类集
    java 四种xml操作方式的基本使用方法
    用JDOM操作XML文件
    java web 学习
    过去的,将来的
  • 原文地址:https://www.cnblogs.com/Francis-YZR/p/5423435.html
Copyright © 2011-2022 走看看