zoukankan      html  css  js  c++  java
  • Quartz系列(一):基础介绍

    新建一个.NET Core控制台项目,NuGet引用Quartz引用。

    class Program
        {
            static void Main(string[] args)
            {
                var task = Task.Run(async () => await RunScheduler());
                task.Wait();
    
                Console.Read();
            }
    
            public static async Task RunScheduler()
            {
                //创建作业调度器
                ISchedulerFactory factory = new StdSchedulerFactory();
                IScheduler scheduler = await factory.GetScheduler();
    
                //启动调度器
                await scheduler.Start();
    
                //创建作业
                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();
    
                //加如到作业调度器
                await scheduler.ScheduleJob(job, trigger);
            }
    
    
            public class HelloJob:IJob
            {
                /// <summary>
                /// 作业调度定时执行的方法
                /// </summary>
                public async Task Execute(IJobExecutionContext context)
                {
                    await Console.Out.WriteLineAsync("Hello QuartzNet...");
                }
            }
        }

    Quartz接口说明:

    IScheduler :和调度器交互的主要接口
    JobBuilder:定义 JobDetail 实例
    IJobDetail:定义 Job 实例及其它相关的静态信息
    IJob:自定义的作业模块所要继承的接口,调度器会调用这个实现
    TriggerBuilder:定义 Trigger 实例
    ITrigger:定义 Job 被触发的时间

    Quartz运行流程:

    1.创建作业调度器 IScheduler

    2.启动调度器

    3.创建作业 IJobDetail

    4.创建触发器 ITrigger

    5.将作业和触发器加入到作业调度器中

    代码说明:

    代码说明:

    通过 StdSchedulerFactory 获取到调度工厂 ISchedulerFactory,通过调度工厂的 GetScheduler 方法获取到一个调度器 scheduler 。初始化调度器 scheduler 之后, 就可以启动、 备用、 关闭。

    通过 JobBuilder 创建一个 IJobDetail 作业详情 ,指定一个 IJob 的实现类 HelloJob ,同时指定了作业详情标识的键名和组名。

    通过 TriggerBuilder 创建一个 ITrigger 触发器,指定了这个触发器标识的键名和组名,触发器只有在启动状态才能工作,这里设置了 StartNow,同时设置了触发器的执行时间,每隔10s执行一次。当 Trigger 触发的时候, HelloJob 的Execute(..) 方法就会在调度器 scheduler 的工作线程中执行,
    这里设置的 RepeatForever 是指在当前守护进程内重复执行,如果程序被关闭了,那必然不会继续执行。

    Quartz理论:

    Job: 是一个接口,只定义一个方法execute(JobExecutionContext context),在实现接口的execute方法中编写所需要定时执行的Job(任务), JobExecutionContext类提供了调度应用的一些信息。Job运行时的信息保存在JobDataMap实例中;
     
     
    JobDetail: **Quartz每次调度Job时, 都重新创建一个Job实例, 所以它不直接接受一个Job的实例,相反它接收一个Job实现类(JobDetail:描述Job的实现类及其它相关的静态信息,如Job名字、描述、关联监听器等信息),以便运行时通过newInstance()的反射机制实例化Job。
     
     
    Trigger: **是一个类,描述触发Job执行的时间触发规则。主要有SimpleTrigger和CronTrigger这两个子类。当且仅当需调度一次或者以固定时间间隔周期执行调度,SimpleTrigger是最适合的选择;而CronTrigger则可以通过Cron表达式定义出各种复杂时间规则的调度方案:如工作日周一到周五的15:00~16:00执行调度等;
    具体cron语法参考这篇文章http://www.jianshu.com/p/9027d067ac5b

     
    Scheduler: **代表一个Quartz的独立运行容器, Trigger和JobDetail可以注册到Scheduler中, 两者在Scheduler中拥有各自的组及名称, 组及名称是Scheduler查找定位容器中某一对象的依据, Trigger的组及名称必须唯一, JobDetail的组和名称也必须唯一(但可以和Trigger的组和名称相同,因为它们是不同类型的)。Scheduler定义了多个接口方法, 允许外部通过组及名称访问和控制容器中Trigger和JobDetail。Scheduler可以将Trigger绑定到某一JobDetail中, 这样当Trigger触发时, 对应的Job就被执行。一个Job可以对应多个Trigger, 但一个Trigger只能对应一个Job。可以通过SchedulerFactory创建一个Scheduler实例。Scheduler拥有一个SchedulerContext,它类似于ServletContext,保存着Scheduler上下文信息,Job和Trigger都可以访问SchedulerContext内的信息。SchedulerContext内部通过一个Map,以键值对的方式维护这些上下文数据,SchedulerContext为保存和获取数据提供了多个put()和getXxx()的方法。可以通过Scheduler# getContext()获取对应的SchedulerContext实例;
     
     
    ThreadPool: **Scheduler使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提高运行效率。Job有一个StatefulJob子接口,代表有状态的任务,该接口是一个没有方法的标签接口,其目的是让Quartz知道任务的类型,以便采用不同的执行方案。无状态任务在执行时拥有自己的JobDataMap拷贝,对JobDataMap的更改不会影响下次的执行。而有状态任务共享共享同一个JobDataMap实例,每次任务执行对JobDataMap所做的更改会保存下来,后面的执行可以看到这个更改,也即每次执行任务后都会对后面的执行发生影响。正因为这个原因,无状态的Job可以并发执行,而有状态的StatefulJob不能并发执行,这意味着如果前次的StatefulJob还没有执行完毕,下一次的任务将阻塞等待,直到前次任务执行完毕。有状态任务比无状态任务需要考虑更多的因素,程序往往拥有更高的复杂度,因此除非必要,应该尽量使用无状态的Job。如果Quartz使用了数据库持久化任务调度信息,无状态的JobDataMap仅会在Scheduler注册任务时保持一次,而有状态任务对应的JobDataMap在每次执行任务后都会进行保存。Trigger自身也可以拥有一个JobDataMap,其关联的Job可以通过JobExecutionContext#getTrigger().getJobDataMap()获取Trigger中的JobDataMap。不管是有状态还是无状态的任务,在任务执行期间对Trigger的JobDataMap所做的更改都不会进行持久,也即不会对下次的执行产生影响。Quartz拥有完善的事件和监听体系,大部分组件都拥有事件,如任务执行前事件、任务执行后事件、触发器触发前事件、触发后事件、调度器开始事件、关闭事件等等,可以注册相应的监听器处理感兴趣的事件。
     
  • 相关阅读:
    小程序 scroll-view 中文字不换行问题
    模块
    网络编程
    元类
    day24
    day23
    day22
    day21
    day18
    day17
  • 原文地址:https://www.cnblogs.com/weiBlog/p/10292994.html
Copyright © 2011-2022 走看看