Quartz.NET是一个开源的做业调度框架,很是适合在平时的工做中,定时轮询数据库同步,定时邮件通知,定时处理数据等。 Quartz.NET容许开发人员根据时间间隔(或天)来调度做业。它实现了做业和触发器的多对多关系,还能把多个做业与不一样的触发器关联。整合了 Quartz.NET的应用程序能够重用来自不一样事件的做业,还能够为一个事件组合多个做业。html
目录java
Quartz.NET是一个强大、开源、轻量的做业调度框架,是 OpenSymphony 的 Quartz API 的.NET移植,用C#改写,可用于winform和asp.net应用中。它灵活而不复杂。你可以用它来为执行一个做业而建立简单的或复杂的做业调度。它有不少特征,如:数据库支持,集群,插件,支持cron-like表达式等等。git
通俗说它的功能是:好比说我想天天晚上2点让程序或网站执行某些代码,或者每隔5秒种我想查看是否有新的任务要处理等。github
官网:http://www.quartz-scheduler.net/数据库
源码:https://github.com/quartznet/quartznetexpress
示例:http://www.quartz-scheduler.net/documentation/quartz-2.x/quick-start.htmljson
其实Quartz是一个彻底由java编写的开源做业调度框架,Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它能够与J2EE与J2SE应用程序相结合也能够单独使用。Quartz能够用来建立简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。而Quartz.Net与NPOI同样是一个DoNet平台下的对应版本。若是您使用Java直接访问这里就行了http://www.quartz-scheduler.org/api
引入框架的方法很是简单你能够直接用nuget管理包也能够在项目中添加引用:服务器
建立一个新项目,能够是ASP.NET MVC,WebForms,Winforms等多种.Net项目,这里使用的是VS2013,建立了一个MVC项目:网络
新版本的Visual Studio默认状况是安装了Nuget的,如Visual Studio2015,但若是没有安装,打开VS菜单“工具”->"扩展与更新"
在扩展与更新中搜索“nuget”,能够新安装或卸载后升级:
为解决国内访问NuGet服务器速度不稳定的问题建议你最好选择一些镜像服务器,这样能够加速下载。
在Visual Studio中的添加方法是:打开“工具”->“选项”菜单
在左侧菜单中找到“NuGet包管理器”
点击右上角的加号,添加两个镜像,这些地址能够上网搜索,我使用的是以下两个:
https://nuget.cnblogs.com/v3/index.json
http://api.nuget.org/v3/index.json
设置一下顺序就OK了。
点击“工具”->"NuGet包管理器"->“程序包管理器控制台”
输入安装包的命令:
Install-Package Quartz
安装结果以下:
此时包管理器中就下载了须要的程序集与相关文件,程序中也添加了引用。
固然若是您不肯意使用nuget也能够下载到Quartz后直接引用,能够在本文尾部下载到框架。
框架下载地址:连接: https://pan.baidu.com/s/1slDM5JJ 密码: 9x5m
假定我如今想当前的MVC应用每隔5秒钟向C:\Quartz.txt文件中记录当前时间。
由于这是一个Web应用,我想网站一启动时就开始该项工做,这里咱们须要打开Global.asax,将代码写在Application_Start方法中
定义一个类,实现Quartz.IJob接口,实现方法Execute,TimeJob.cs文件的代码以下:
using Quartz; using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MvcApplication1 { public class TimeJob : IJob { public void Execute(IJobExecutionContext context) { //向c:\Quartz.txt写入当前时间并换行 System.IO.File.AppendAllText(@"c:\Quartz.txt", DateTime.Now+Environment.NewLine); } } }
调度器负责管理与控制任务的执行,在Global.asax文件的Application_Start方法中添加以下代码:
//调度器 IScheduler scheduler; //调度器工厂 ISchedulerFactory factory; //建立一个调度器 factory = new StdSchedulerFactory(); scheduler = factory.GetScheduler(); scheduler.Start();
这个任务对象就是咱们将要执行的工做,job1是名称,group1是组名。
//二、建立一个任务 IJobDetail job = JobBuilder.Create<TimeJob>().WithIdentity("job1", "group1").Build();
触发器定义了什么时间任务开始或每隔多久执行一次。
//三、建立一个触发器 //DateTimeOffset runTime = DateBuilder.EvenMinuteDate(DateTimeOffset.UtcNow); ITrigger trigger = TriggerBuilder.Create() .WithIdentity("trigger1", "group1") .WithCronSchedule("0/5 * * * * ?") //5秒执行一次 //.StartAt(runTime) .Build();
//四、将任务与触发器添加到调度器中 scheduler.ScheduleJob(job, trigger); //五、开始执行 scheduler.Start();
当网站关闭时结束正在执行的工做,在Global.asax中的Application_End方法中添加以下代码:
protected void Application_End(object sender, EventArgs e) { // 在应用程序关闭时运行的代码 if (scheduler != null) { scheduler.Shutdown(true); } }
shutdown方法中的参数true的意思为:是否等待任务的完成再结束。
using Quartz; using Quartz.Impl; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Http; using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; namespace MvcApplication1 { public class MvcApplication : System.Web.HttpApplication { //调度器 IScheduler scheduler; //调度器工厂 ISchedulerFactory factory; protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); AuthConfig.RegisterAuth(); //一、建立一个调度器 factory = new StdSchedulerFactory(); scheduler = factory.GetScheduler(); scheduler.Start(); //二、建立一个任务 IJobDetail job = JobBuilder.Create<TimeJob>().WithIdentity("job1", "group1").Build(); //三、建立一个触发器 //DateTimeOffset runTime = DateBuilder.EvenMinuteDate(DateTimeOffset.UtcNow); ITrigger trigger = TriggerBuilder.Create() .WithIdentity("trigger1", "group1") .WithCronSchedule("0/5 * * * * ?") //5秒执行一次 //.StartAt(runTime) .Build(); //四、将任务与触发器添加到调度器中 scheduler.ScheduleJob(job, trigger); //五、开始执行 scheduler.Start(); } protected void Application_End(object sender, EventArgs e) { // 在应用程序关闭时运行的代码 if (scheduler != null) { scheduler.Shutdown(true); } } } }
看官方的示例、源码或帮助文档能够了解更多的使用方法,官方帮助的地址是:https://www.quartz-scheduler.net/documentation/index.html
cron表达式就是用于设定时间的一个字符串,在前面的代码中咱们就用到了,以下所示:
//三、建立一个触发器 //DateTimeOffset runTime = DateBuilder.EvenMinuteDate(DateTimeOffset.UtcNow); ITrigger trigger = TriggerBuilder.Create() .WithIdentity("trigger1", "group1") .WithCronSchedule("0/5 * * * * ?") //5秒执行一次 //.StartAt(runTime) .Build();
官方英文介绍:http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/crontrigger.html
cron expressions 总体上仍是很是容易理解的,只有一点须要注意:"?"号的用法,看下文能够知道“?”能够用在 day of month 和 day of week中,他主要是为了解决以下场景,如:每个月的1号的每小时的31分钟,正确的表达式是:* 31 * 1 * ?,而不能是:* 31 * 1 * *,由于这样表明每周的任意一天。
/* 由7段构成:秒 分 时 日 月 星期 年(可选) "-" :表示范围 MON-WED表示星期一到星期三 "," :表示列举 MON,WEB表示星期一和星期三 "*" :表是“每”,每个月,天天,每周,每一年等 "/" :表示增量:0/15(处于分钟段里面) 每15分钟,在0分之后开始,3/20 每20分钟,从3分钟之后开始 "?" :只能出如今日,星期段里面,表示不指定具体的值 "L" :只能出如今日,星期段里面,是Last的缩写,一个月的最后一天,一个星期的最后一天(星期六) "W" :表示工做日,距离给定值最近的工做日 "#" :表示一个月的第几个星期几,例如:"6#3"表示每月的第三个星期五(1=SUN...6=FRI,7=SAT) 若是Minutes的数值是 '0/15' ,表示从0开始每15分钟执行 若是Minutes的数值是 '3/20' ,表示从3开始每20分钟执行,也就是‘3/23/43’ */
官方示例:
表达式 | 解释 |
---|---|
0 0 12 * * ? | 天天中午12点触发 |
0 15 10 ? * * | 天天上午10:15触发 |
0 15 10 * * ? | 天天上午10:15触发 |
0 15 10 * * ? * | 天天上午10:15触发 |
0 15 10 * * ? 2005 | 2005年的天天上午10:15触发 |
0 * 14 * * ? | 在天天下午2点到下午2:59期间的每1分钟触发 |
0 0/5 14 * * ? | 在天天下午2点到下午2:55期间的每5分钟触发 |
0 0/5 14,18 * * ? | 在天天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 |
0 0-5 14 * * ? | 在天天下午2点到下午2:05期间的每1分钟触发 |
0 10,44 14 ? 3 WED | 每一年三月的星期三的下午2:10和2:44触发 |
0 15 10 ? * MON-FRI | 周一至周五的上午10:15触发 |
0 15 10 15 * ? | 每个月15日上午10:15触发 |
0 15 10 L * ? | 每个月最后一日的上午10:15触发 |
0 15 10 L-2 * ? | 每月的次日到最后一天的上午10:15触发 |
0 15 10 ? * 6L | 每个月的最后一个星期五上午10:15触发 |
0 15 10 ? * 6L | 每月最后一个星期五上午10时15分触发 |
0 15 10 ? * 6L 2002-2005 | 2002年至2005年的每个月的最后一个星期五上午10:15触发 |
0 15 10 ? * 6#3 | 每个月的第三个星期五上午10:15触发 |
0 0 12 1/5 * ? | 每个月每隔5天下午12点(中午)触发, 从每个月的第一天开始 |
0 11 11 11 11 ? | 每11月11日上午11时11分触发 |
请查看帮助文档、示例或上网搜索,:),后面有空再补充吧
IIS能够设置定时自动回收,默认回收是1740分钟,也就是29小时。IIS自动回收至关于服务器IIS重启,应用程序池内存清空,全部数据被清除,至关于IIS重启,在度量快速开发平台服务器端,为了减少数据库负担,内存中暂存了不少信息,不适合频繁的回收,由于回收会形成服务器端全部存在内存中的数据丢失,若是没有及时保存到数据库中,可能致使程序出现问题。而若是系统使用高峰时期,并不适合回收,回收可能致使几十秒IIS无响应,对于正在工做的人员来讲,是一种很很差的体验,会觉得是网络或者掉线等问题。
若是IIS重启则Global.asax中的方法将被再次执行,若是不想IIS自动重启可使用以下的设置:
IIS应用程序池回收,找到相应的应用程序池并点击高级设置,就能够看到回收的相关设置
发生配置更改时禁止回收:若是为True,应用程序池在发生配置更改时将不会回收。
固定时间间隔(分钟):超过设置的时间后,应用程序池回收,为0意味着应用程序池不会按固定间隔回收。系统默认设置的时间是1740(29小时)。
禁用重叠回收:若是为true,将发生应用程序池回收,以便在建立另外一个工做进程以前退出现有工做进程。
请求限制:应用程序池在回收以前能够处理的最大请求数。若是值为0,则表示应用程序池能够处理的请求数没有限制。
生成回收事件日志条目:每发生一次指定的回收事件时便产生一个事件日志条目。
更多参考:http://www.cnblogs.com/Fishwood/p/3602041.html
一、实现定时任务的方法有不少,若是很是简单的话直接使用系统内置的Timer,Scheduler,Cache都是能够达到的,但要注意GC回收的问题,通常会定义成静态的。
二、本文只是很是粗浅的介绍了一下零配置的方法,您也能够选择使用XML配置的方式替代部分的硬编码。
示例下载 密码: 9x5m
框架下载 密码: 9x5m