The first talk about what is Quartz.Net

正如標題所示,文章主要是圍繞Quartz.Net做業調度框架話題展開的,內容出自博主學習官方Examples的學習心得與體會,文中不免會有錯誤之處,還請指出得以指教。html

在百度一下搜索Quartz.Net,能夠知道Quartz.Net是Net版本的任務調度框架,是一個從java移植過來的Net版本的開源框架,在做業調度方面提供了很好的靈活性而不犧牲簡單,可以爲執行一個做業而建立簡單的或複雜的調度,目前版本支持數據庫,集羣,插件配置,支持cron表達式等等java

Quartz Enterprise Schedulder .Netweb

官方下載地址:數據庫

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

官方文檔:ide

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

到此咱們大概瞭解了一下Quartz.Net是什麼,在繼續討論相關Quartz以前,咱們先來思考並解決一個問題。學習

假設程序有這麼一個需求,在必定的時間間隔裏,輪詢作一種操做或者任務,我想首先固然能夠這麼實現:ui

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

運行的結果以下:spa

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.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的使用話題。

相關文章
相關標籤/搜索