zoukankan      html  css  js  c++  java
  • 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,现在是时候启动并运行一个示例应用程序了。 以下代码获取调度程序的实例,启动它,然后将其关闭:

     1     using System;
     2     using System.Threading.Tasks;
     3 
     4     using Quartz;
     5     using Quartz.Impl;
     6 
     7     namespace QuartzSampleApp
     8     {
     9         public class Program
    10         {
    11             private static void Main(string[] args)
    12             {
    13                 // trigger async evaluation
    14                 RunProgram().GetAwaiter().GetResult();
    15             }
    16 
    17             private static async Task RunProgram()
    18             {
    19                 try
    20                 {
    21                     // 从Factory获取Scheduler实例
    22                     NameValueCollection props = new NameValueCollection
    23                     {
    24                         { "quartz.serializer.type", "binary" }
    25                     };
    26                     StdSchedulerFactory factory = new StdSchedulerFactory(props);
    27                     IScheduler scheduler = await factory.GetScheduler();
    28 
    29                     // 并启动它
    30                     await scheduler.Start();
    31 
    32                     // some sleep to show what's happening
    33                     await Task.Delay(TimeSpan.FromSeconds(10));
    34 
    35                     // 当您准备关闭程序时,最后关闭调度程序
    36                     await scheduler.Shutdown();
    37                 }
    38                 catch (SchedulerException se)
    39                 {
    40                     await Console.Error.WriteLineAsync(se.ToString());
    41                 }
    42             }
    43         }
    44     }


        从Quartz 3.0开始,当在scheduler.Shutdown() 之后没有剩下的代码要执行时,你的应用程序将终止,因为没有任何活动的线程。 如果希望在处理Task.Delay和Shutdown之后调度程序继续运行,则应手动阻止退出应用程序。

        现在运行该程序将不会显示任何内容。 10秒后,程序将终止。 让我们添加一些日志记录到控制台。    

    五、增加日志功能

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

        当LibLog没有检测到任何其他日志框架存在时,它将是不做任何事的。 如果您还没有一个设置好的日志框架,我们可以配置一个自定义的日志记录器提供程序,只需登录到控制台即可显示输出。
        
       

     1 LogProvider.SetCurrentLogProvider(new ConsoleLogProvider());
     2 
     3     private class ConsoleLogProvider : ILogProvider
     4     {
     5         public Logger GetLogger(string name)
     6         {
     7             return (level, func, exception, parameters) =>
     8             {
     9                 if (level >= LogLevel.Info && func != null)
    10                 {
    11                     Console.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] [" + level + "] " + func(), parameters);
    12                 }
    13                 return true;
    14             };
    15         }
    16 
    17         public IDisposable OpenNestedContext(string message)
    18         {
    19             throw new NotImplementedException();
    20         }
    21 
    22         public IDisposable OpenMappedContext(string key, string value)
    23         {
    24             throw new NotImplementedException();
    25         }
    26     }


    六、探索使用 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来向控制台输出问候语。

    1     public sealed class HelloJob : IJob
    2     {
    3         public async Task Execute(IJobExecutionContext context)
    4         {
    5             await Console.Out.WriteLineAsync("Greetings from HelloJob!");
    6         }
    7     }

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

     1     // 定义job作业并将其绑定到HelloJob类
     2     IJobDetail job = JobBuilder.Create<HelloJob>()
     3     .WithIdentity("job1", "group1")
     4     .Build();
     5 
     6     //触发作业立即运行,然后每10秒重复一次
     7     ITrigger trigger = TriggerBuilder.Create()
     8     .WithIdentity("trigger1", "group1")
     9     .StartNow()
    10     .WithSimpleSchedule(x => x
    11         .WithIntervalInSeconds(10)
    12         .RepeatForever())
    13     .Build();
    14 
    15     //告诉 quartz 使用我们的触发器安排作业
    16     await scheduler.ScheduleJob(job, trigger);


        完整的控制台应用程序现在看起来像这样

      1     using System;
      2     using System.Threading.Tasks;
      3 
      4     using Quartz;
      5     using Quartz.Impl;
      6     using Quartz.Logging;
      7 
      8     namespace QuartzSampleApp
      9     {
     10         public class Program
     11         {
     12             private static void Main(string[] args)
     13             {
     14                 LogProvider.SetCurrentLogProvider(new ConsoleLogProvider());
     15 
     16                 RunProgram().GetAwaiter().GetResult();
     17 
     18                 Console.WriteLine("Press any key to close the application");
     19                 Console.ReadKey();
     20             }
     21 
     22             private static async Task RunProgram()
     23             {
     24                 try
     25                 {
     26                     // Grab the Scheduler instance from the Factory
     27                     NameValueCollection props = new NameValueCollection
     28                     {
     29                         { "quartz.serializer.type", "binary" }
     30                     };
     31                     StdSchedulerFactory factory = new StdSchedulerFactory(props);
     32                     IScheduler scheduler = await factory.GetScheduler();
     33 
     34                     // and start it off
     35                     await scheduler.Start();
     36 
     37                     // define the job and tie it to our HelloJob class
     38                     IJobDetail job = JobBuilder.Create<HelloJob>()
     39                         .WithIdentity("job1", "group1")
     40                         .Build();
     41 
     42                     // Trigger the job to run now, and then repeat every 10 seconds
     43                     ITrigger trigger = TriggerBuilder.Create()
     44                         .WithIdentity("trigger1", "group1")
     45                         .StartNow()
     46                         .WithSimpleSchedule(x => x
     47                             .WithIntervalInSeconds(10)
     48                             .RepeatForever())
     49                         .Build();
     50 
     51                     // Tell quartz to schedule the job using our trigger
     52                     await scheduler.ScheduleJob(job, trigger);
     53 
     54                     // some sleep to show what's happening
     55                     await Task.Delay(TimeSpan.FromSeconds(60));
     56 
     57                     // and last shut down the scheduler when you are ready to close your program
     58                     await scheduler.Shutdown();
     59                 }
     60                 catch (SchedulerException se)
     61                 {
     62                     Console.WriteLine(se);
     63                 }
     64             }
     65 
     66             // simple log provider to get something to the console
     67             private class ConsoleLogProvider : ILogProvider
     68             {
     69                 public Logger GetLogger(string name)
     70                 {
     71                     return (level, func, exception, parameters) =>
     72                     {
     73                         if (level >= LogLevel.Info && func != null)
     74                         {
     75                             Console.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] [" + level + "] " + func(), parameters);
     76                         }
     77                         return true;
     78                     };
     79                 }
     80 
     81                 public IDisposable OpenNestedContext(string message)
     82                 {
     83                     throw new NotImplementedException();
     84                 }
     85 
     86                 public IDisposable OpenMappedContext(string key, string value)
     87                 {
     88                     throw new NotImplementedException();
     89                 }
     90             }
     91         }
     92 
     93         public class HelloJob : IJob
     94         {
     95             public async Task Execute(IJobExecutionContext context)
     96             {
     97                 await Console.Out.WriteLineAsync("Greetings from HelloJob!");
     98             }
     99         }
    100     }


        现在去探索Quartz.NET吧! 您可以继续阅读本教程。原文地址如下:https://www.quartz-scheduler.net/documentation/quartz-3.x/quick-start.html

  • 相关阅读:
    10、mysql序列使用、数据去重
    9、mysql临时表、复制表
    记一次FileOutputStream出现FileNotFoundException(stale file handle)的问题
    记一次ORACLE报ORA-02290: 违反检查约束条件错误
    TreeUtil---生成树状结构数据
    Redis
    Redis事务
    Redis工具类
    Nginx
    EasyExcel动态导出数据
  • 原文地址:https://www.cnblogs.com/PatrickLiu/p/9982424.html
Copyright © 2011-2022 走看看