【轉】Quartz.NET快速入門指南

最近,在工作中遇到了 Quartz.net 這個組件,爲了更好的理解項目代碼的來龍去脈,於是決定好好的研究一下這個東西。確實是好東西,既然是好東西,我就拿出來分享一下。萬丈高樓平地起,我們也從入門開始吧。

      歡迎使用 Quartz.NET 快速入門指南。 在閱讀本指南時,必須注意以下條目:

           1、下載 Quartz.NET

           2、安裝 Quartz.NET

           3、根據您自己的特定需求來配置 Quartz.Net

           4、展示一個示例應用程序


一、下載並安裝

      您可以直接下載 ZIP 文件或使用 NuGet 包來獲取文件。二者是有區別的,NuGet 包只包含運行 Quartz.NET 所必須的二進制文件,ZIP 文件就不一樣了,包含源代碼、示例和 Quartz.NET 服務器示例應用程序。

      Zip文件

      簡短版本:如果你成功下載了 Quartz.NET 壓縮包文件,只要將 ZIP 文件解壓,從bin目錄中獲取 Quartz.dll 文件,就可以開始使用它了。

      Quartz.Net 的核心庫是一個非常乾淨和獨立的類庫,不會強行依賴任何其他的二進制文件。 如果您想使用JSON.NET進行JSON序列化時,您可以根據需要選擇加入更多的程序集。同時您只要保證在應用程序中包含了 Quartz.dll 文件就可以成功運行 Quartz.NET,也會和其他的二進制文件相處融洽。 因此,只要將 Quartz.dll 文件添加到使用它們的 Visual Studio 項目中就可以完美的運行。 您可以從路徑bin \ your-target-framework-version \ release \ Quartz 中提取的文檔中找到這些 dll。

二、NuGet包

      這是最簡單的做法了,只需啓動Visual Studio(安裝了NuGet)並從包管理器擴展中添加對Quartz包的引用:

           1、右鍵單擊項目的“引用”(References),然後選擇“管理 NuGet 程序包(N)”(Manage NuGet Packages(N)) ...
           2、從左側選擇“瀏覽or在線”類別
           3、在左上方的搜索中輸入 Quartz,然後按 回車 鍵
           4、從搜索結果中選擇 Quartz.NET 並點擊安裝
           5、完成!

      或者使用NuGet的命令行來安裝:

    Install-Package Quartz


      如果想要添加 JSON  序列化的功能,只需以相同的方式添加 Quartz.Serialization.Json 包就可以。

三、配置

      Quartz.NET 是一個支持靈活配置的庫。Quartz.NET 提供三種的配置信息的方式(不相互排斥):

          1、以編程方式通過向調度程序工廠提供 NameValueCollection 參數

          2、通過使用 quartz-element 的標準 youapp.exe.config 配置文件(僅限完整的.NET框架)

          3、可以使用應用程序根目錄中的  quartz.config 文件(適用於.NET Core和完整的.NET Framework)

      您可以在Quartz.NET zip文件中找到所有這些替代品的樣本。

      Quartz Configuration Reference中提供了可用屬性的完整文檔。

     爲了加速啓動和運行,提供了最基本的配置信息的文件 quartz.config 看起來應該像這樣:

    quartz.scheduler.instanceName = MyScheduler
    quartz.jobStore.type = Quartz.Simpl.RAMJobStore,Quartz
    quartz.threadPool.threadCount = 3

      請記住在 Visual Studio 的文件屬性頁上設置“複製到輸出目錄”以使值始終爲“複製”。否則,配置文件就不會存在構建項目的目錄中,就不會使用該配置文件。

      此配置創建的調度程序具有以下特徵:

          quartz.scheduler.instanceName - 此調度程序的名稱將爲“MyScheduler”。
          quartz.threadPool.threadCount - 最多可同時運行3個作業。
          quartz.jobStore.type - 所有 Quartz 的數據,例如作業和觸發器的詳細信息,都保存在內存中(而不是數據庫中)。即使你有一個數據庫並希望在 Quartz 中使用它,我建議你在使用數據庫打開一個全新的維度之前讓 Quartz 使用 RamJobStore。

      實際上,如果你不想定義這些屬性,Quartz.NET會提供合理的默認值

四、先看一個簡單的示例程序

      現在您已經下載並安裝了Quartz,現在是時候啓動並運行一個示例應用程序了。 以下代碼獲取調度程序的實例,啓動它,然後將其關閉:

using System;
    using System.Threading.Tasks;

    using Quartz;
    using Quartz.Impl;

    namespace QuartzSampleApp
    {
        public class Program
        {
            private static void Main(string[] args)
            {
                // trigger async evaluation
                RunProgram().GetAwaiter().GetResult();
            }

            private static async Task RunProgram()
            {
                try
                {
                    // 從Factory獲取Scheduler實例
                    NameValueCollection props = new NameValueCollection
                    {
                        { "quartz.serializer.type", "binary" }
                    };
                    StdSchedulerFactory factory = new StdSchedulerFactory(props);
                    IScheduler scheduler = await factory.GetScheduler();

                    // 並啓動它
                    await scheduler.Start();

                    // some sleep to show what's happening
                    await Task.Delay(TimeSpan.FromSeconds(10));

                    // 當您準備關閉程序時,最後關閉調度程序
                    await scheduler.Shutdown();
                }
                catch (SchedulerException se)
                {
                    await Console.Error.WriteLineAsync(se.ToString());
                }
            }
        }
    }

    從Quartz 3.0開始,當在scheduler.Shutdown() 之後沒有剩下的代碼要執行時,你的應用程序將終止,因爲沒有任何活動的線程。 如果希望在處理Task.Delay和Shutdown之後調度程序繼續運行,則應手動阻止退出應用程序。

    現在運行該程序將不會顯示任何內容。 10秒後,程序將終止。 讓我們添加一些日誌記錄到控制檯。    

五、增加日誌功能

    LibLog可以配置爲使用不同的日誌框架; 即Log4Net,NLog和Serilog。

    當LibLog沒有檢測到任何其他日誌框架存在時,它將是不做任何事的。 如果您還沒有一個設置好的日誌框架,我們可以配置一個自定義的日誌記錄器提供程序,只需登錄到控制檯即可顯示輸出。

LogProvider.SetCurrentLogProvider(new ConsoleLogProvider());

    private class ConsoleLogProvider : ILogProvider
    {
        public Logger GetLogger(string name)
        {
            return (level, func, exception, parameters) =>
            {
                if (level >= LogLevel.Info && func != null)
                {
                    Console.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] [" + level + "] " + func(), parameters);
                }
                return true;
            };
        }

        public IDisposable OpenNestedContext(string message)
        {
            throw new NotImplementedException();
        }

        public IDisposable OpenMappedContext(string key, string value)
        {
            throw new NotImplementedException();
        }
    }

 六、探索使用 Job 作業的完整過程

    現在,當我們啓動應用程序時,我們應該獲得更多信息。

[10:52:50] [Info] Using object serializer: Quartz.Simpl.BinaryObjectSerializer, Quartz
    [10:52:50] [Info] Initialized Scheduler Signaller of type: Quartz.Core.SchedulerSignalerImpl
    [10:52:50] [Info] Quartz Scheduler v.3.0.7.0 created.
    [10:52:50] [Info] RAMJobStore initialized.
    [10:52:50] [Info] Scheduler meta-data: Quartz Scheduler (v3.0.7.0) 'QuartzScheduler' with instanceId 'NON_CLUSTERED'
      Scheduler class: 'Quartz.Core.QuartzScheduler' - running locally.
      NOT STARTED.
      Currently in standby mode.
      Number of jobs executed: 0
      Using thread pool 'Quartz.Simpl.DefaultThreadPool' - with 10 threads.
      Using job-store 'Quartz.Simpl.RAMJobStore' - which does not support persistence. and is not clustered.

    [10:52:50] [Info] Quartz scheduler 'QuartzScheduler' initialized
    [10:52:50] [Info] Quartz scheduler version: 3.0.7.0
    [10:52:50] [Info] Scheduler QuartzScheduler_$_NON_CLUSTERED started.

  我們需要一個簡單的測試工作來測試功能,讓我們創建HelloJob來向控制檯輸出問候語。

public sealed class HelloJob : IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
            await Console.Out.WriteLineAsync("Greetings from HelloJob!");
        }
    }

  要做一些有趣的事情,您需要在Task.Delay之前的Start() 方法之後使用代碼。

// 定義job作業並將其綁定到HelloJob類
    IJobDetail job = JobBuilder.Create<HelloJob>()
    .WithIdentity("job1", "group1")
    .Build();

    //觸發作業立即運行,然後每10秒重複一次
    ITrigger trigger = TriggerBuilder.Create()
    .WithIdentity("trigger1", "group1")
    .StartNow()
    .WithSimpleSchedule(x => x
        .WithIntervalInSeconds(10)
        .RepeatForever())
    .Build();

    //告訴 quartz 使用我們的觸發器安排作業
    await scheduler.ScheduleJob(job, trigger);

   完整的控制檯應用程序現在看起來像這樣

using System;
    using System.Threading.Tasks;

    using Quartz;
    using Quartz.Impl;
    using Quartz.Logging;

    namespace QuartzSampleApp
    {
        public class Program
        {
            private static void Main(string[] args)
            {
                LogProvider.SetCurrentLogProvider(new ConsoleLogProvider());

                RunProgram().GetAwaiter().GetResult();

                Console.WriteLine("Press any key to close the application");
                Console.ReadKey();
            }

            private static async Task RunProgram()
            {
                try
                {
                    // Grab the Scheduler instance from the Factory
                    NameValueCollection props = new NameValueCollection
                    {
                        { "quartz.serializer.type", "binary" }
                    };
                    StdSchedulerFactory factory = new StdSchedulerFactory(props);
                    IScheduler scheduler = await factory.GetScheduler();

                    // and start it off
                    await scheduler.Start();

                    // define the job and tie it to our HelloJob class
                    IJobDetail job = JobBuilder.Create<HelloJob>()
                        .WithIdentity("job1", "group1")
                        .Build();

                    // Trigger the job to run now, and then repeat every 10 seconds
                    ITrigger trigger = TriggerBuilder.Create()
                        .WithIdentity("trigger1", "group1")
                        .StartNow()
                        .WithSimpleSchedule(x => x
                            .WithIntervalInSeconds(10)
                            .RepeatForever())
                        .Build();

                    // Tell quartz to schedule the job using our trigger
                    await scheduler.ScheduleJob(job, trigger);

                    // some sleep to show what's happening
                    await Task.Delay(TimeSpan.FromSeconds(60));

                    // and last shut down the scheduler when you are ready to close your program
                    await scheduler.Shutdown();
                }
                catch (SchedulerException se)
                {
                    Console.WriteLine(se);
                }
            }

            // simple log provider to get something to the console
            private class ConsoleLogProvider : ILogProvider
            {
                public Logger GetLogger(string name)
                {
                    return (level, func, exception, parameters) =>
                    {
                        if (level >= LogLevel.Info && func != null)
                        {
                            Console.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] [" + level + "] " + func(), parameters);
                        }
                        return true;
                    };
                }

                public IDisposable OpenNestedContext(string message)
                {
                    throw new NotImplementedException();
                }

                public IDisposable OpenMappedContext(string key, string value)
                {
                    throw new NotImplementedException();
                }
            }
        }

        public class HelloJob : IJob
        {
            public async Task Execute(IJobExecutionContext context)
            {
                await Console.Out.WriteLineAsync("Greetings from HelloJob!");
            }
        }
    }

    現在去探索Quartz.NET吧! 您可以繼續閱讀本教程。原文地址如下:https://www.quartz-scheduler.net/documentation/quartz-3.x/quick-start.html

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章