注:目前网上诸多介绍Quartz.net的文章,甚至Quartz.net官网上的Tutorial都是1.0版本的,而这个项目在2.0版本对项目进行了比较大规模的修改,使得原有的很多例子都不能运行,故写此文。由于本人是边学边用,加之技术写作水平皆有限,错误自然难免,望轻拍,我将不定时更新完善此贴,希望能为需要的朋友提供帮助。
现今的系统,业务数据是越来越大,传统的同步处理方式有时候已经不能满足用户需求,定时后台服务这种异步数据处理形式则逐渐被大家接受。相信大家在平时的工作中也经常遇到数据同步,或是定时邮件,短信提醒等需求,Quartz.net(官网 http://quartznet.sourceforge.net/)可以很好满足对多个windows服务的管理及监控,同时在保证开发简单的情况下不失灵活,是非常优秀的作业调度框架。
和其他绝大多数开源项目一样Quartz.net也包含了其他几个优秀的开源项目:
核心 ----Common.Logging(通用日志接口)
----C5(泛型集合类)
示例程序
----log4net(日志记录-通用日志接口实现)
----topshelf(跨平台服务宿主程序)
Quartz.net使用的许可是Apache License,商业友好,使用者可以修改源码用于开源或商业项目,只需包含许可及修改说明。
Scheduler ---------主调度程序 --------- Quartz核心
Job ---------作业 --------- 服务要做的(业务操作)
Trigger ---------触发器 --------- 服务执行条件(何时执行操作)
Listener ---------事件监听器 --------- 执行期事件(Job执行前后/ Scheduler启动终止暂停时应该做什么,可以挂一些特定事件)
了解了这些概念之后,我们就可以组合这些概念并整理出开发的思路:
先利用SchedulerFactory构建一个Scheduler,启动Scheduler,之后构建Job和Trigger,若有作业监听需求,在Listener上添加相应的处理程序,再将Job和Trigger关联后放入Scheduler
3. Quartz.net的简单使用
1. 新建一个控制台程序,引用Quartz.dll和Common.Logging.dll
2. 新建一个类,命名为SampleJob,继承并实现接口Quartz.IJob
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class SampleJob : IJob
{
public void Execute(IJobExecutionContext context)
{
File.AppendAllText("C:\\Quartz.txt", "SampleJob Is Run");
File.AppendAllText("C:\\Quartz.txt", Environment.NewLine);
}
}
3.在Program.cs的main方法中写如下代码后运行这个控制台会程序会发现已经SampleJob中的Execute方法已经执行
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
ISchedulerFactory factory = new StdSchedulerFactory();
IScheduler scheduler = factory.GetScheduler();
scheduler.Start();
IJobDetail job = JobBuilder.Create<SampleJob>().WithIdentity("SampleJob", "JobGroup1").Build();
ITrigger trigger = TriggerBuilder.Create().StartNow().Build();
scheduler.ScheduleJob(job, trigger);
4. 使用topshelf创建WINDOWS服务
注:此部分张善友同学已经写过 (http://www.cnblogs.com/shanyou/archive/2011/05/04/2037008.html),此节为保证思路连贯,简单介绍并引用部分代码
也许有的网友会疑问,以控制台程序作为服务宿主还没有意义的,这时轮到Topshelf出场了, 使用它可以很方便的构建跨平台服务寄主,而在调试时直接以控制台的形式运行即可,非常方便。 我们引入topshelf.dll及 log4net.dll(topshelf需要),将之前main中代码放到服务类里,把main方法变为Host构建
服务类代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class SampleService
{
ISchedulerFactory factory;
IScheduler scheduler;
public void Start()
{
File.AppendAllText("C:\\Quartz.txt", "SampleService Is Run");
File.AppendAllText("C:\\Quartz.txt", Environment.NewLine);
factory = new StdSchedulerFactory();
scheduler = factory.GetScheduler();
scheduler.Start();
IJobDetail job = JobBuilder.Create<SampleJob>().WithIdentity("SampleJob", "JobGroup1").Build();
ITrigger trigger = TriggerBuilder.Create().StartNow().Build();
scheduler.ScheduleJob(job, trigger);
}
public void Stop()
{
scheduler.Clear();
File.AppendAllText("C:\\Quartz.txt", "SampleService Is Stop");
File.AppendAllText("C:\\Quartz.txt", Environment.NewLine);
}
}
修改后的Main代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
static void Main(string[] args)
{
var host = HostFactory.New(x =>
{
x.EnableDashboard(); x.Service<SampleService>(s =>
{
s.SetServiceName("SampleService"); s.ConstructUsing(name => new SampleService());
s.WhenStarted(tc => { tc.Start(); });
s.WhenStopped(tc => tc.Stop());
});
x.RunAsLocalSystem();
x.SetDescription("SampleService Description");
x.SetDisplayName("SampleService");
x.SetServiceName("SampleService");
});
host.Run();
}
编译后,cmd进到exe所在目录,并执行"项目名.exe install/uninstall" 完成服务的安装与卸载