一. 背景
工作中我們難免會(huì)有這樣一些需求:定時(shí)任務(wù),說(shuō)白了就是在某一時(shí)間,讓我們的程序來(lái)執(zhí)行一些工作.
說(shuō)道這里,也你會(huì)想到windows計(jì)劃任務(wù),但在一些時(shí)候它并沒(méi)有很好的擴(kuò)展性,一些復(fù)雜的任務(wù)并不能很好的完成,不能滿足的我們的工作需要,我們需要的是一個(gè)集群部署的作業(yè)調(diào)度框架间狂。
二. Quartz.Net介紹
Quartz.NET是一個(gè)開(kāi)源的作業(yè)調(diào)度框架,非常適合在平時(shí)的工作中审洞,定時(shí)輪詢數(shù)據(jù)庫(kù)同步,定時(shí)郵件通知调窍,定時(shí)處理數(shù)據(jù)等若锁。 Quartz.NET允許開(kāi)發(fā)人員根據(jù)時(shí)間間隔(或天)來(lái)調(diào)度作業(yè)泽台。它實(shí)現(xiàn)了作業(yè)和觸發(fā)器的多對(duì)多關(guān)系,還能把多個(gè)作業(yè)與不同的觸發(fā)器關(guān)聯(lián)访娶。整合了Quartz.NET的應(yīng)用程序可以重用來(lái)自不同事件的作業(yè)商虐,還可以為一個(gè)事件組合多個(gè)作業(yè).
它一些很好的特性:
1:支持集群,作業(yè)分組崖疤,作業(yè)遠(yuǎn)程管理秘车。
2:自定義精細(xì)的時(shí)間觸發(fā)器,使用簡(jiǎn)單劫哼,作業(yè)和觸發(fā)分離叮趴。
3:數(shù)據(jù)庫(kù)支持,可以寄宿Windows服務(wù)权烧,WebSite眯亦,winform等。
三. 實(shí)戰(zhàn)
利用nuget來(lái)安裝 Quartz.Net
Quartz框架的基礎(chǔ)概念解釋:
Scheduler 作業(yè)調(diào)度器般码。
IJob 作業(yè)接口妻率,繼承并實(shí)現(xiàn)Execute, 編寫執(zhí)行的具體作業(yè)邏輯板祝。
JobBuilder 根據(jù)設(shè)置宫静,生成一個(gè)詳細(xì)作業(yè)信息(JobDetail)。
TriggerBuilder 根據(jù)規(guī)則,生產(chǎn)對(duì)應(yīng)的Trigger
編寫類CronTask.cs 實(shí)現(xiàn)IJob囊嘉,在Execute方法里編寫要處理的業(yè)務(wù)邏輯温技,系統(tǒng)就會(huì)按照Quartz的配置,定時(shí)處理扭粱。
public sealed class CronTask : IJob
{
private static Logger logger = LogManager.GetCurrentClassLogger();
public void Execute(IJobExecutionContext context)
{
//可以通過(guò)context對(duì)象來(lái)獲取傳遞過(guò)來(lái)的一些數(shù)據(jù)數(shù)據(jù)
JobDataMap dataMap = context.MergedJobDataMap;
string tag = dataMap.GetString("tag");
string title = dataMap.GetString("title");
string content = dataMap.GetString("content");
string description = dataMap.GetString("description");
string tels = dataMap.GetString("tels");
//執(zhí)行定時(shí)任務(wù) 發(fā)送短信
SendMsg(tels,content);
context.Scheduler.Shutdown();
logger.InfoFormat("定時(shí)任務(wù)測(cè)試");
}
//定義任務(wù)
public static void SetTask(string tag, string starttime, string title, string content, string description,string tels)
{
try
{
DateTime time = DateTime.Parse(starttime);
//下面用到的執(zhí)行時(shí)間要使用Cron表達(dá)式(如:"/5 * * ? * *"),下面我會(huì)介紹一下
string cronstr = GetCron(time);
//從工廠中獲取一個(gè)調(diào)度器實(shí)例化
IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
scheduler.Start();
var jobData = new JobDataMap();
jobData.Add("tag", tag);
jobData.Add("title", title);
jobData.Add("content", content);
jobData.Add("description", description);
jobData.Add("tels", tels);
IJobDetail job = JobBuilder.Create<CronTask>()
.WithIdentity("job", DateTime.Now.ToLongDateString())
.SetJobData(jobData)
.Build();
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("msmtriger", "group")
.StartNow() //現(xiàn)在開(kāi)始
.WithCronSchedule(cronstr)
.Build();
// ITrigger trigger2 = TriggerBuilder.Create()
// .WithIdentity("mytrigger", "group1")
// .StartNow()
// .WithCronSchedule("/5 * * ? * *") //時(shí)間表達(dá)式,5秒一次
// .Build();
scheduler.ScheduleJob(job, trigger);//把作業(yè)震檩,觸發(fā)器加入調(diào)度器琢蛤。
}
catch (Exception ex)
{
logger.Error(ex);
}
}
public static string GetCron(DateTime dt)
{
string retulut = "";
retulut = string.Format("0,{0} 0,{1} 0,{2} {3} {4} ? {5}", dt.Second, dt.Minute, dt.Hour, dt.Day, dt.Month, dt.Year);
return retulut;
}
}
WithCronSchedule("") 擁有強(qiáng)大的Cron時(shí)間表達(dá)式,正常情況下WithSimpleSchedule(x) 已經(jīng)滿足大部分對(duì)日期設(shè)置的要求了抛虏。
上面說(shuō)道的cron表達(dá)式可以參考:
http://www.cnblogs.com/yanweidie/p/3537144.html
里面的在線地址已經(jīng)不能用了,我這里給大家準(zhǔn)備了一個(gè):
Quartz Cron表達(dá)式在線生成器