前言

Quartz3与Quartz2的主要区别有两点:

1,Quartz3将它的资源类库拆的更细了,比如,想使用Quartz3开发,最少要引用Quartz,Quartz.Jobs,Quartz.Plugins这三个类库。

2,Quartz3整体上使用的是异步创建实例,所以我们使用时就必须要async,await的语法。

下面我们用Quartz3来做一个任务调度。

创建调度器管理类

首先创建Jops类库,然后在Nuget中搜索Quartz.Plugins;如下图:

因为Quartz.Plugins依赖于Quartz,所以引入Quartz.Plugins就会自动引入Quartz。

然后我们创建任务调度管理类—ScheduleControler。代码如下:

public class ScheduleControler

{
private static IScheduler scheduler;
private static Dictionary<IJobDetail, IReadOnlyCollection<ITrigger>> dicJop = new Dictionary<IJobDetail, IReadOnlyCollection<ITrigger>>(); private static int triggerId = 0;
private static string defaultGroupName = "默认组";
/// <summary>
/// 初始化调度器
/// </summary>
/// <returns></returns>
public static async Task Init()
{
try
{
//quartz.config配置文件里的键值对
//NameValueCollection props = new NameValueCollection
//{
// { "quartz.serializer.type", "binary" }
//};
StdSchedulerFactory factory = new StdSchedulerFactory();
scheduler = await factory.GetScheduler();
await scheduler.Start();
}
catch (SchedulerException se)
{
System.Console.WriteLine(se);
}
}
/// <summary>
/// 运行调度器任务
/// </summary>
/// <returns></returns>
public static async Task Run()
{
try
{
await scheduler.ScheduleJobs(dicJop, true);

}
catch (SchedulerException se)
{
System.Console.WriteLine(se);
}
}
/// <summary>
/// 关闭调度器
/// </summary>
/// <returns></returns>
public static async Task Shutdown()
{
try
{
await scheduler.Shutdown();

}
catch (SchedulerException se)
{
System.Console.WriteLine(se);
}
}
/// <summary>
/// 添加任务
/// </summary>
/// <typeparam name="T">任务类型,继承Ijop</typeparam>
/// <param name="jopName">任务名</param>
/// <param name="Interval">运行间隔时间/秒**最小为1秒</param>
/// <param name="period">等待启动时间/秒**-1为马上启动</param>
/// <param name="repeatTime">重复次数**-1为永远运行</param>
/// <param name="endAt">在指定时间后结束/秒**0为不指定结束时间,默认值0</param>
public static void PushJop<T>(string jopName, int Interval, int period=-1,int repeatTime=-1,int endAt=0) where T:IJob
{
try
{
if (Interval <= 0)
{
Interval = 1;
}
if (period < -1)
{
period = -1;
}
if (repeatTime < -1)
{
repeatTime = -1;
}
if (endAt < 0)
{
endAt = -1;
}
IJobDetail job = JobBuilder.Create<T>().WithIdentity(jopName, defaultGroupName).UsingJobData("Name", "IJobDetail").Build(); var triggerBuilder = TriggerBuilder.Create().WithIdentity($"{jopName}.trigger{triggerId}", defaultGroupName);
if (period == -1)
{
triggerBuilder = triggerBuilder.StartNow();
}
else
{
DateTimeOffset dateTimeOffset = DateTimeOffset.Now.AddSeconds(period);
triggerBuilder = triggerBuilder.StartAt(dateTimeOffset);
}
if (endAt > 0)
{
triggerBuilder = triggerBuilder.EndAt(new DateTimeOffset(DateTime.Now.AddSeconds(endAt)));
}

if (repeatTime == -1)
{
triggerBuilder = triggerBuilder.WithSimpleSchedule(x => x.WithIntervalInSeconds(Interval).RepeatForever());
}
else
{
triggerBuilder = triggerBuilder.WithSimpleSchedule(x => x.WithRepeatCount(Interval).WithRepeatCount(repeatTime));
}
ITrigger trigger = triggerBuilder.UsingJobData("Name", "ITrigger")
.WithPriority(triggerId)//设置触发器优先级,当有多个触发器在相同时间出发时,优先级最高[数字最大]的优先
.Build();

dicJop.Add(job, new HashSet<ITrigger>() { trigger });
triggerId++;
}
catch (SchedulerException se)
{
System.Console.WriteLine(se);
}
}

public static void PushJop<T>(string jopName, string cronExpress) where T : IJob
{
try
{
IJobDetail job = JobBuilder.Create<T>().WithIdentity(jopName, defaultGroupName).UsingJobData("Name", "IJobDetail").Build();
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity($"{jopName}.trigger{triggerId}", defaultGroupName)
.WithCronSchedule(cronExpress)
.ForJob(job)
.Build();
dicJop.Add(job, new HashSet<ITrigger>() { trigger });
triggerId++;
}
catch (SchedulerException se)
{
System.Console.WriteLine(se);
}
}
}

可以看到调度器管理类中包含四个主要函数,如下:

运行调度器任务(Run)

初始化调度器(Init)

关闭调度器(Shutdown)

添加任务(PushJop)

应用程序通过这四个函数的调用,就可以使用Quartz了。

添加配置文件

quartz.config

quartz.config是调度器工厂StdSchedulerFactory的配置文件,我们可以在初始化调度器时配置,但显然在配置文件里设置更易于修改。

quartz.config内容如下:

# You can configure your scheduler in either <quartz> configuration section
# or in quartz properties file
# Configuration section has precedence

quartz.scheduler.instanceName = QuartzTest

# configure thread pool info
quartz.threadPool.type = Quartz.Simpl.SimpleThreadPool, Quartz
quartz.threadPool.threadCount = 10
quartz.threadPool.threadPriority = Normal

# job initialization plugin handles our xml reading, without it defaults are used
quartz.plugin.xml.type = Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz.Plugins
#指定quartz_jobs.xml路径
#quartz.plugin.xml.fileNames = ~/quartz_jobs.xml

# export this server to remoting context 使用CrystalQuartz 放开如下注释
quartz.scheduler.exporter.type = Quartz.Simpl.RemotingSchedulerExporter, Quartz
quartz.scheduler.exporter.port = 555
quartz.scheduler.exporter.bindName = QuartzScheduler
quartz.scheduler.exporter.channelType = tcp
quartz.scheduler.exporter.channelName = httpQuartz

如果在初始化时配置,参考如下代码:

NameValueCollection props = new NameValueCollection
{
{ "quartz.serializer.type", "binary" }
};
StdSchedulerFactory factory = new StdSchedulerFactory(props);

quartz_jobs.xml

quartz_jobs.xml是任务配置文件,用于配置任务的。不过本文的调度器管理类已经通过的PushJop函数对任务进行了配置,所以就不需要在quartz_jobs.xml文件中配置了,不过为了测试方便,我们还是添加一个quartz_jobs.xml文件,因为quartz.config文件中指定配置了quartz_jobs.xml,所以没有它会异常。

这里我们添加一个空的quartz_jobs.xml文件,如下:

<?xml version="1.0" encoding="UTF-8"?>
<!-- This file contains job definitions in schema version 2.0 format -->
<job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
<processing-directives>
<overwrite-existing-data>true</overwrite-existing-data>
</processing-directives>
<schedule>
</schedule>
</job-scheduling-data>

创建任务

创建一个任务类(Jop)用于处理业务操作,任务类需继承IJop接口,代码如下。

 public class HelloJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
Task task = new Task(() => {
LogicMethod(context);
});
task.Start();
await task;
}
public void LogicMethod(IJobExecutionContext context)
{
Console.Out.WriteLine($"HelloJob DateTime:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} Key:{context.JobDetail.Key} ");
}
} 

测试Quartz

创建一个新控制台项目—QuartzNetTest,引入Jops类库和Quartz.Plugins。

然后修改Main函数,配置HelloJob任务每三秒运行一次,如下:

static void Main(string[] args)
{
ScheduleControler.Init().GetAwaiter().GetResult();
ScheduleControler.PushJop<HelloJob>("HelloWord", 3);
ScheduleControler.Run().GetAwaiter().GetResult();
var info = Console.ReadKey();
if (info.Key == ConsoleKey.Enter)
{
ScheduleControler.Shutdown().GetAwaiter().GetResult();
Console.WriteLine("结束");
}
Console.Read();
}

运行项目,如下图:

Quartz运行成功。

Quartz任务管理器

QuartzNet除了定时运行任务,还提供了任务管理器。下面我们一起新建一个Quartz的任务管理。

创建一个空的Web项目——QuartzNetWebManager。

添加依赖类库

Nuget搜索CrystalQuartz.Remote安装。

再搜索Quartz安装,注意这里安装的Quartz不是Quartz.Plugins。

这样Quartz的任务管理就创建完成了。

然后我们打开WebConfig,可以看到configuration下多了一个crystalQuartz节点,webServer下多了一个handlers,阅读配置文件,发现Quartz的任务管理器指定了网页CrystalQuartzPanel.axd为访问地址,。

WebConfig如下:

<crystalQuartz>
<provider>
<add property="Type" value="CrystalQuartz.Core.SchedulerProviders.RemoteSchedulerProvider, CrystalQuartz.Core" />
<!-- Edit scheduler host value below =================================== -->
<add property="SchedulerHost" value="tcp://localhost:555/QuartzScheduler" />
<!-- =================================== -->
</provider>
</crystalQuartz>
<system.webServer>
<handlers>
<add name="CrystalQuartzPanel" verb="*" path="CrystalQuartzPanel.axd" type="CrystalQuartz.Web.PagesHandler, CrystalQuartz.Web" />
</handlers>
</system.webServer>

访问网址https://localhost:44302/CrystalQuartzPanel.axd,管理界面如下:

可以看到管理器中除了显示当前运行的任务,还提供删除任务,马上执行等等功能;非常方便。

当然,Quartz还有很多功能,我们可以去官网学习。

QuartzNet官网:https://www.quartz-scheduler.net/

----------------------------------------------------------------------------------------------------

代码已经传到Github上了,欢迎大家下载。

Github地址:https://github.com/kiba518/QuartzTest

----------------------------------------------------------------------------------------------------

注:此文章为原创,任何形式的转载都请联系作者获得授权并注明出处!
若您觉得这篇文章还不错,请点击下方的【推荐】,非常感谢!

https://www.cnblogs.com/kiba/p/12794928.html

Quartz3.0定时任务学习之异步调度器的更多相关文章

  1. Cocos2d-X3.0 刨根问底(六)----- 调度器Scheduler类源码分析

    上一章,我们分析Node类的源码,在Node类里面耦合了一个 Scheduler 类的对象,这章我们就来剖析Cocos2d-x的调度器 Scheduler 类的源码,从源码中去了解它的实现与应用方法. ...

  2. 泡面不好吃,我用了这篇k8s调度器,征服了他

    1.1 调度器简介 来个小刘一起 装逼吧 ,今天我们来学习 K8的调度器 Scheduler是 Kubernetes的调度器,主要的任务是把定义的 pod分配到集群的节点上,需要考虑以下问题: 公平: ...

  3. 转: 调整 Linux I/O 调度器优化系统性能

    转自:https://www.ibm.com/developerworks/cn/linux/l-lo-io-scheduler-optimize-performance/index.html 调整 ...

  4. Linux 调度器发展简述

    引言 进程调度是操作系统的核心功能.调度器只是是调度过程中的一部分,进程调度是非常复杂的过程,需要多个系统协同工作完成.本文所关注的仅为调度器,它的主要工作是在所有 RUNNING 进程中选择最合适的 ...

  5. Yarn 容量调度器多队列提交案例

    目录 Yarn 容量调度器多队列提交案例 需求 配置多队列的容量调度器 1 修改如下配置 SecureCRT的上传和下载 2 上传到集群并分发 3 重启Yarn或yarn rmadmin -refre ...

  6. Quartz定时任务学习(四)调度器

    org.quartz.Scheduler 类层次 作为一个 Quartz 用户,你要与实现了 org.quartz.Scheduler 接口的类交互.在你调用它的任何 API 之前,你需要知道如何创建 ...

  7. quartz2.3.0(十三)数据库持久化定时器job任务和trigger触发器,在多个调度器实例情况下,由其它调度器实例恢复执行调度器宕机的job任务

    一.初始化数据库11张quartz表:qrtz_*   先从官网下载好quartz2.3.0包:http://www.quartz-scheduler.org/downloads/ 解压后进入目录:q ...

  8. 图解kubernetes调度器ScheduleAlgorithm核心实现学习框架设计

    ScheduleAlgorithm是一个接口负责为pod选择一个合适的node节点,本节主要解析如何实现一个可扩展.可配置的通用算法框架来实现通用调度,如何进行算法的统一注册和构建,如何进行metad ...

  9. java定时任务以及Spring使用Quartz调度器执行定时任务

    java下的java.util.Timer中类可以实现定时执行任务的执行: 如:让任务立即执行,每隔1s循环执行一次 public class TimerClass { public static v ...

随机推荐

  1. centos7与8的区别

    1.关于内核版本:RHEL8采用4.18.0-xRHEL7采用3.10-0-x 2 网络时间同步 RHEL8 只使用Chronyd,不支持NTP部署. RHEL7Chronyd与NTP两者都支持 3. ...

  2. 如何用hugo 搭建博客

    1,Hugo 简介 搭建个人博客有很多开源的博客框架,我们要介绍的框架叫作Hugo.Hugo 是一个基于Go 语言的框架,可以快速方便的创建自己的博客. Hugo 支持Markdown 语法,我们可以 ...

  3. HashMap源码解析JDK8

    一.HashMap基础 1.1 HashMap的定义 我们先看一下HashMap的定义: public class HashMap<K,V> extends AbstractMap< ...

  4. 基于Apache+Tomcat实现负载均衡

    1.基于Apache和tomcat实现负载均衡 准备三个虚拟机一个安装Apache两个安装Tomcat 关闭防火墙 systemctl stop firewalld Iptabled -F Seten ...

  5. java 之 servlet简介

    Servlet 是什么? Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间 ...

  6. SAP WM TO Print Control设置里,Movement Type 的优先级更高

    SAP WM TO Print Control设置里,Movement Type 的优先级更高 存储类型的配置: 从storage type GRM 搬到任何地方,都不需要打印TO单. 移动类型的配置 ...

  7. 解决w3wp.exe占用CPU和内存问题

    在WINDOWS2003+IIS6下,经常出现w3wp的内存占用不能及时释放,从而导致服务器响应速度很慢.可以做以下配置进行改善:1.在IIS中对每个网站进行单独的应用程序池配置.即互相之间不影响.2 ...

  8. Docker 1.13.0 详细更新日志

    本文讲的是Docker 1.13.0 详细更新日志[编者的话]Docker发布1.13.0版本,此次版本更新内容较多,以下为该版本具体的变更. 构建 添加在构建时可以指定镜像用作高速缓存源的功能. 这 ...

  9. App 自动化环境搭建

    1.安装 Appium-desktop 工具 下载地址:https://github.com/appium/appium-desktop/releases 2.安装 Android 环境 安装 JDK ...

  10. 商汤提出解偶检测中分类和定位分支的新方法TSD,COCO 51.2mAP | CVPR 2020

    目前很多研究表明目标检测中的分类分支和定位分支存在较大的偏差,论文从sibling head改造入手,跳出常规的优化方向,提出TSD方法解决混合任务带来的内在冲突,从主干的proposal中学习不同的 ...