Quartz.net 起步
安装 Quartz 程序包
使用 nuget 命令行安装 Quartz:
Install-Package Quartz
如果使用 JSON 序列化,使用 nuget 安装 Quartz.Serialization.Json。
配置 Quartz
可通过三种方式配置Quartz
- 编程式配置,用 NameValueCollection 为 SchedulerFactory 提供参数
- 通过 app.config 文件,这种方式仅适用于 full .net framework
- 通过 quartz.config,此文件需放在应用程序的根目录,这种方式适用于 full .net framework 和 .net core
程序骨架
以下代码创建 Scheduler 实例,启动它,最后关闭。
using System;
using System.Collections.Specialized;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl; namespace QuartzSampleApp
{
public class Program
{
private static void Main(string[] args)
{
// 异步执行
RunProgram().GetAwaiter().GetResult();
} private static async Task RunProgram()
{
try
{
// 从工厂获取 Scheduler 实例
NameValueCollection props = new NameValueCollection
{
{ "quartz.serializer.type", "binary" }
};
StdSchedulerFactory factory = new StdSchedulerFactory(props);
IScheduler scheduler = await factory.GetScheduler(); // 启动 Scheduler 实例
await scheduler.Start(); // 停60秒看效果
await Task.Delay(TimeSpan.FromSeconds()); // 关闭程序前关闭 scheduler
await scheduler.Shutdown();
}
catch (SchedulerException se)
{
await Console.Error.WriteLineAsync(se.ToString());
}
}
}
}
通过 StdSchedulerFactory.GetDefaultScheduler() 方法获取到 scheduler 实例后,直到调用 scheduler.Shutdown() 前,应用程序不会退出。因为存在后台线程。
添加日志
Quartz.net 使用 LibLog,可适配 Log4Net,NLog 和Serilog等日志框架。没有检测到这些日志框架时,LibLog不输出内容。下面的自定义 LoggerProvider 在没有使用日志框架的情况下向控制台输出消息:
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();
}
}
使用自定义LogProvider:
private static void Main(string[] args)
{
LogProvider.SetCurrentLogProvider(new ConsoleLogProvider()); // 异步执行
RunProgram().GetAwaiter().GetResult();
}
添加作业
使用 IJob 接口自定义作业
public class HelloJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
await Console.Out.WriteLineAsync("Greetings from HelloJob!");
}
}
使用作业,在调用 Start 方法之后加入以下代码:
// 定义作业,关联到 HelloJob
IJobDetail job = JobBuilder.Create<HelloJob>()
.WithIdentity("job1", "group1")
.Build(); // 立即触发,然后每 10 秒触发一次
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds()
.RepeatForever())
.Build(); // 指示 quartz 使用触发器调度作业
await scheduler.ScheduleJob(job, trigger);
完整代码
using System;
using System.Collections.Specialized;
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();
} private static async Task RunProgram()
{
try
{
// 从工厂获取 Scheduler 实例
NameValueCollection props = new NameValueCollection
{
{ "quartz.serializer.type", "binary" }
};
StdSchedulerFactory factory = new StdSchedulerFactory(props);
IScheduler scheduler = await factory.GetScheduler(); // 启动 Scheduler 实例
await scheduler.Start(); // 定义作业,关联到 HelloJob
IJobDetail job = JobBuilder.Create<HelloJob>()
.WithIdentity("job1", "group1")
.Build(); // 立即触发,然后每 10 秒触发一次
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds()
.RepeatForever())
.Build(); // 指示 quartz 使用触发器调度作业
await scheduler.ScheduleJob(job, trigger); // 停60秒看效果
await Task.Delay(TimeSpan.FromSeconds()); // 关闭程序前关闭 scheduler
await scheduler.Shutdown();
}
catch (SchedulerException se)
{
await Console.Error.WriteLineAsync(se.ToString());
}
} 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!");
}
}
}
程序输出
程序启动后,输出以下内容:
[16:31:41] [Info] Using object serializer: Quartz.Simpl.BinaryObjectSerializer, Quartz
[16:31:41] [Info] Initialized Scheduler Signaller of type: Quartz.Core.Scheduler SignalerImpl
[16:31:41] [Info] Quartz Scheduler v.3.0.2.0 created.
[16:31:41] [Info] RAMJobStore initialized.
[16:31:41] [Info] Scheduler meta-data: Quartz Scheduler (v3.0.2.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. [16:31:41] [Info] Quartz scheduler 'QuartzScheduler' initialized
[16:31:41] [Info] Quartz scheduler version: 3.0.2.0
[16:31:41] [Info] Scheduler QuartzScheduler_$_NON_CLUSTERED started.
Greetings from HelloJob!
Greetings from HelloJob!
Greetings from HelloJob!
Greetings from HelloJob!
Greetings from HelloJob!
Greetings from HelloJob!
Greetings from HelloJob!
[16:32:41] [Info] Scheduler QuartzScheduler_$_NON_CLUSTERED shutting down.
[16:32:41] [Info] Scheduler QuartzScheduler_$_NON_CLUSTERED paused.
[16:32:41] [Info] Scheduler QuartzScheduler_$_NON_CLUSTERED Shutdown complete.
请按任意键继续. . .
Quartz.net 起步的更多相关文章
- Quartz中文文档使用
Quartz中文使用说明文档,内容相当详细,有需要的码友们可以看看!! 好东西要分享!! 下面是文档的内容目录,附上下载的地址:点击打开链接,下载文档 中文版目录总汇及内容提要 第一章. 企业应用中的 ...
- 免费开源的DotNet任务调度组件Quartz.NET(.NET组件介绍之五)
很多的软件项目中都会使用到定时任务.定时轮询数据库同步,定时邮件通知等功能..NET Framework具有“内置”定时器功能,通过System.Timers.Timer类.在使用Timer类需要面对 ...
- Quartz
Quartz是一个开源的作业调度框架,它完全由Java写成,并设计用于J2SE和J2EE应用中.它提供了巨大的灵 活性而不牺牲简单性.你能够用它来为执行一个作业而创建简单的或复杂的调度. eg: ja ...
- Spring Quartz实现任务调度
任务调度 在企业级应用中,经常会制定一些"计划任务",即在某个时间点做某件事情 核心是以时间为关注点,即在一个特定的时间点,系统执行指定的一个操作 任务调度涉及多线程并发.线程池维 ...
- topshelf和quartz内部分享
阅读目录: 介绍 基础用法 调试及安装 可选配置 多实例支持及相关资料 quartz.net 上月在公司内部的一次分享,现把PPT及部分交流内容整理成博客. 介绍 topshelf是创建windows ...
- [NodeJS] Hello World 起步教程
概述: 做数据,免不了需要展示数据,数据可视化是必须经历的步骤. 本文将提供一个NodeJS的起步教程,是笔者这两天探索的小结. 正文: 1. 为什么使用NodeJS 究竟是以B/S还是C/S的架构 ...
- Quartz.net持久化与集群部署开发详解
序言 我前边有几篇文章有介绍过quartz的基本使用语法与类库.但是他的执行计划都是被写在本地的xml文件中.无法做集群部署,我让它看起来脆弱不堪,那是我的罪过. 但是quart.net是经过许多大项 ...
- Quartz.net开源作业调度框架使用详解
前言 quartz.net作业调度框架是伟大组织OpenSymphony开发的quartz scheduler项目的.net延伸移植版本.支持 cron-like表达式,集群,数据库.功能性能强大更不 ...
- quartz.net 时间表达式----- Cron表达式详解
序言 Cron表达式:就是用简单的xxoo符号按照一定的规则,就能把各种时间维度表达的淋漓尽致,无所不在其中,然后在用来做任务调度(定时服务)的quart.net中所认知执行,可想而知这是多么的天衣无 ...
随机推荐
- grep匹配字符串出现的次数
背景:想要匹配一个html页面中某个字符出现的次数 遇到的问题: 用grep -c “xxx字符”得到的是行数,如果一行中有多个匹配到的字符,只会算作一个 解决方法: 使用grep - ...
- angluarjs ng-repeat 行号
参考 https://zhidao.baidu.com/question/1882914672116911828.html $index
- mysql数据类型长度
1个字节= 8位 tinyint 为一个字节 2的8次方= 256 所以最多存储到256 日期和时间数据类型 MySQL数据类型 含义 date 3字节,日期,格式:2014-09-18 time ...
- Linux Shell 文本处理工具集锦(转载)
内容目录: find 文件查找 grep 文本搜索 xargs 命令行参数转换 sort 排序 uniq 消除重复行 用tr进行转换 cut 按列切分文本 paste 按列拼接文本 wc 统计行和字符 ...
- 第七章 二叉搜索树 (d3)AVL树:删除
- 使用VisualSVN Server搭建SVN服务器[xyytit]
使用 VisualSVN Server来实现主要的 SVN功能则要比使用原始的 SVN和 Apache相配合来实现源代码的 SVN管理简单的多,上手也没有那么复杂. 下面就看看详细的说明 Visual ...
- iOS8 之后 tableview separatorInset cell分割线左对齐,ios7的方法失效了
-(void)viewDidLayoutSubviews { if ([self.mytableview respondsToSelector:@selector(setSeparatorInset: ...
- 【校招面试 之 网络】第1题 TCP和UDP
TCP UDP1.TCP与UDP基本区别 (1)基于连接与无连接 (2)TCP要求系统资源较多,UDP较少: (3)UDP程序结构较简单(头只有8个字节:源端口号.目标端口号.长度.差错) ...
- [leetcode]117. Populating Next Right Pointers in Each NodeII用next填充同层相邻节点
Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *nex ...
- discuz回贴通知插件实现-显示用户状态设置
一.完善用户是否开启回贴通知 回贴通知插件建立模块时,指定了核心文件post_set.inc.php 1.创立好数据库 建立独立数据表(不建议直接修改原有的discuz数据库,防止discuz升级 ...