Quartz.Net使用方法詳解_第1頁
Quartz.Net使用方法詳解_第2頁
Quartz.Net使用方法詳解_第3頁
Quartz.Net使用方法詳解_第4頁
Quartz.Net使用方法詳解_第5頁
已閱讀5頁,還剩10頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第Quartz.Net使用方法詳解目錄HelloQuartz.Net作業(yè):Job和JobDetailJobDataJobDetail持久化JobData觸發(fā)器:TriggerSampleTriggerCronTrigger日歷:Calendar監(jiān)聽器JobListenerTriggerListenerSchedulerListener持久化:JobStoreADO.NET存儲負(fù)載均衡通過Routing訪問Quartz實例開發(fā)實踐參考資料在項目的開發(fā)過程中,難免會遇見后需要后臺處理的任務(wù),例如定時發(fā)送郵件通知、后臺處理耗時的數(shù)據(jù)處理等,這個時候你就需要Quartz.Net了。

Quartz.Net是純凈的,它是一個.Net程序集,是非常流行的Java作業(yè)調(diào)度系統(tǒng)Quartz的C#實現(xiàn)。

Quartz.Net一款功能齊全的任務(wù)調(diào)度系統(tǒng),從小型應(yīng)用到大型企業(yè)級系統(tǒng)都能適用。功能齊全體現(xiàn)在觸發(fā)器的多樣性上面,即支持簡單的定時器,也支持Cron表達(dá)式;即能執(zhí)行重復(fù)的作業(yè)任務(wù),也支持指定例外的日歷;任務(wù)也可以是多樣性的,只要繼承IJob接口即可。

對于小型應(yīng)用,Quartz.Net可以集成到你的系統(tǒng)中,對于企業(yè)級系統(tǒng),它提供了Routing支持,提供了Group來組織和管理任務(wù),此外還有持久化、插件功能、負(fù)載均衡和故障遷移等滿足不同應(yīng)用場景的需要。

HelloQuartz.Net

開始使用一個框架,和學(xué)習(xí)一門開發(fā)語言一樣,最好是從HelloWorld程序開始。

首先創(chuàng)建一個示例程序,然后添加Quartz.Net的引用。

Install-PackageQuartz-Version3.0.7

我們使用的是當(dāng)前最新版本3.0.7進(jìn)行演示。添加引用以后,來創(chuàng)建一個Job類HelloQuartzJob。

publicclassHelloQuartzJob:IJob

publicTaskExecute(IJobExecutionContextcontext)

returnTask.Factory.StartNew(()=

Console.WriteLine("HelloQuartz.Net");

}

這是個非常簡單的Job類,它在執(zhí)行時輸出文本HelloQuartz.Net。

接下來,我們在程序啟動時創(chuàng)建調(diào)度器(Scheduler),并添加HelloQuartzJob的調(diào)度:

staticasyncTaskMainAsync()

varschedulerFactory=newStdSchedulerFactory();

varscheduler=awaitschedulerFactory.GetScheduler();

awaitscheduler.Start();

Console.WriteLine($"任務(wù)調(diào)度器已啟動");

//創(chuàng)建作業(yè)和觸發(fā)器

varjobDetail=JobBuilder.CreateHelloQuartzJob().Build();

vartrigger=TriggerBuilder.Create()

.WithSimpleSchedule(m={

m.WithRepeatCount(3).WithIntervalInSeconds(1);

.Build();

//添加調(diào)度

awaitscheduler.ScheduleJob(jobDetail,trigger);

}

然后運行程序,你會看到如下圖:

通過演示可以看出,要執(zhí)行一個定時任務(wù),一般需要四步:

創(chuàng)建任務(wù)調(diào)度器。調(diào)度器通常在應(yīng)用程序啟動時創(chuàng)建,一個應(yīng)用程序?qū)嵗ǔV恍枰粋€調(diào)度器即可。

創(chuàng)建Job和JobDetail。Job是作業(yè)的類型,描述了作業(yè)是如何執(zhí)行的,這個類是由我們定義的;JobDetail是Quartz對作業(yè)的封裝,它包含Job類型,以及Job在執(zhí)行時用到的數(shù)據(jù),還包括是否要持久化、是否覆蓋已存在的作業(yè)等選項。

創(chuàng)建觸發(fā)器。觸發(fā)器描述了在何時執(zhí)行作業(yè)。

添加調(diào)度。當(dāng)完成以上三步以后,就可以對作業(yè)進(jìn)行調(diào)度了。

作業(yè):Job和JobDetail

Job是作業(yè)的類型,描述了作業(yè)是如何執(zhí)行的,這個類型是由我們定義的,例如上文的HelloQuartzJob。Job實現(xiàn)IJob接口,而IJob接口只有一個Execute方法,參數(shù)context中包含了與當(dāng)前上下文中關(guān)聯(lián)的Scheduler、JobDetail、Trigger等。

一個典型的Job定義如下:

publicclassHelloQuartzJob:IJob

publicTaskExecute(IJobExecutionContextcontext)

returnTask.Factory.StartNew(()=

Console.WriteLine("HelloQuartz.Net");

}

JobData

Job不是孤立存在的,它需要執(zhí)行的參數(shù),這些參數(shù)如何傳遞進(jìn)來呢?我們來定義一個Job類進(jìn)行演示。

publicclassSayHelloJob:IJob

publicstringUserName{get;set;}

publicTaskExecute(IJobExecutionContextcontext)

returnTask.Factory.StartNew(()=

Console.WriteLine($"Hello{UserName}!");

}

SayHelloJob在執(zhí)行時需要參數(shù)UserName,這個參數(shù)被稱為JobData,Quartz.Net通過JobDataMap的方式傳遞參數(shù)。代碼如下:

//創(chuàng)建作業(yè)

varjobDetail=JobBuilder.CreateSayHelloJob()

.SetJobData(newJobDataMap(){

newKeyValuePairstring,object("UserName","Tom")

.Build();

通過JobBuilder的SetJobData方法,傳入JobDataMap對象,JobDataMap對象中可以包含多個參數(shù),這些參數(shù)可以映射到Job類的屬性上。我們完善代碼運行示例,可以看到如下圖:

JobDetail

JobDetail是Quartz對作業(yè)的封裝,它包含Job類型,以及Job在執(zhí)行時用到的數(shù)據(jù),還包括是否孤立存儲、請求恢復(fù)作業(yè)等選項。

JobDetail是通過JobBuilder進(jìn)行創(chuàng)建的。例如:

varjobDetail=JobBuilder.CreateSayHelloJob()

.SetJobData(newJobDataMap(){

newKeyValuePairstring,object("UserName","Tom")

.StoreDurably(true)

.RequestRecovery(true)

.WithIdentity("SayHelloJob-Tom","DemoGroup")

.WithDescription("SayhellotoTomjob")

.Build();

參數(shù)說明:

SetJobData:設(shè)置JobData

StoreDurably:孤立存儲,指即使該JobDetail沒有關(guān)聯(lián)的Trigger,也會進(jìn)行存儲

RequestRecovery:請求恢復(fù),指應(yīng)用崩潰后再次啟動,會重新執(zhí)行該作業(yè)

WithIdentity:作業(yè)的唯一標(biāo)識

WithDescription:作業(yè)的描述信息

除此之外,Quartz.Net還支持兩個非常有用的特性:

DisallowConcurrentExecution:禁止并行執(zhí)行,該特性是針對JobDetail生效的

PersistJobDataAfterExecution:在執(zhí)行完成后持久化JobData,該特性是針對Job類型生效的,意味著所有使用該Job的JobDetail都會在執(zhí)行完成后持久化JobData。

持久化JobData

我們來演示一下該PersistJobDataAfterExecution特性,在SayHelloJob中,我們新加一個字段RunSuccess,記錄任務(wù)是否執(zhí)行成功。

首先在SayHelloJob添加特性:

[PersistJobDataAfterExecution]

publicclassSayHelloJob:IJob{}

然后在創(chuàng)建JobDetail時添加JobData:

varjobDetail=JobBuilder.CreateSayHelloJob()

.SetJobData(newJobDataMap(){

newKeyValuePairstring,object("UserName","Tom"),

newKeyValuePairstring,object("RunSuccess",false)

})

在執(zhí)行時Job時,更新RunSuccess的值:

publicTaskExecute(IJobExecutionContextcontext)

returnTask.Factory.StartNew(()=

Console.WriteLine($"PrevRunSuccess:{RunSuccess}");

Console.WriteLine($"Hello{UserName}!");

context.JobDetail.JobDataMap.Put("RunSuccess",true);

}

接下來看一下執(zhí)行效果:

觸發(fā)器:Trigger

Trigger是觸發(fā)器,用來定制執(zhí)行作業(yè)。Trigger有兩種類型:SampleTrigger和CronTrigger,我們分別進(jìn)行說明。

SampleTrigger

顧名思義,這是個簡單的觸發(fā)器,有以下特性:

重復(fù)執(zhí)行:WithRepeatCount()/RepeatForever()

設(shè)置間隔時間:WithInterval()

定時執(zhí)行:StartAt()/StartNow()

設(shè)定優(yōu)先級:WithPriority(),默認(rèn)為5

需要注意:當(dāng)Trigger到達(dá)StartAt指定的時間時會執(zhí)行一次,這一次執(zhí)行是不包含在WithRepeatCount中的。在我們上面的例子中可以看出,添加調(diào)度后會立即執(zhí)行一次,然后重復(fù)三次,最終執(zhí)行了四次。

CronTrigger

CronTrigger是通過Cron表達(dá)式來完成調(diào)度的。Cron表達(dá)式非常靈活,可以實現(xiàn)幾乎各種定時場景的需要。

關(guān)于Cron表達(dá)式,大家可以移步QuartzCron表達(dá)式

使用CronTrigger的示例如下:

vartrigger=TriggerBuilder.Create()

.WithCronSchedule("*/1****")

.Build();

日歷:Calendar

Calendar可以與Trigger進(jìn)行關(guān)聯(lián),從Trigger中排出執(zhí)行計劃。例如你只希望在工作日執(zhí)行作業(yè),那么我們可以定義一個休息日的日歷,將它與Trigger關(guān)聯(lián),從而排出休息日的執(zhí)行計劃。

Calendar示例代碼如下:

varcalandar=newHolidayCalendar();

calandar.AddExcludedDate(DateTime.Today);

awaitscheduler.AddCalendar("holidayCalendar",calandar,false,false);

vartrigger=TriggerBuilder.Create()

.WithCronSchedule("*/1****")

.ModifiedByCalendar("holidayCalendar")

.Build();

在這個示例中,我們創(chuàng)建了HolidayCalendar日歷,然后添加排除執(zhí)行的日期。我們把今天添加到排除日期后,該Trigger今天將不會觸發(fā)。

監(jiān)聽器

JobListeners

TriggerListeners

SchedulerListeners

監(jiān)聽器是Quartz.Net的另外一個出色的功能,它允許我們編寫監(jiān)聽器達(dá)到在運行時獲取作業(yè)狀態(tài)、處理作業(yè)數(shù)據(jù)等功能。

JobListener

JobListener可以監(jiān)聽Job執(zhí)行前、執(zhí)行后、否決執(zhí)行的事件。我們通過代碼進(jìn)行演示:

publicclassMyJobListener:IJobListener

publicstringName{get;}=nameof(MyJobListener);

publicTaskJobToBeExecuted(IJobExecutionContextcontext,CancellationTokencancellationToken=default)

//Job即將執(zhí)行

returnTask.Factory.StartNew(()=

Console.WriteLine($"Job:{context.JobDetail.Key}即將執(zhí)行");

publicTaskJobExecutionVetoed(IJobExecutionContextcontext,CancellationTokencancellationToken=default)

returnTask.Factory.StartNew(()={

Console.WriteLine($"Job:{context.JobDetail.Key}被否決執(zhí)行");

publicTaskJobWasExecuted(IJobExecutionContextcontext,JobExecutionExceptionjobException,CancellationTokencancellationToken=default)

//Job執(zhí)行完成

returnTask.Factory.StartNew(()=

Console.WriteLine($"Job:{context.JobDetail.Key}執(zhí)行完成");

定義完成后,將MyJobListener添加到Scheduler中:

scheduler.ListenerManager.AddJobListener(newMyJobListener(),GroupMatcherJobKey.AnyGroup());

然后我們再運行程序,就可以看到Listener被調(diào)用了:

通過圖片可以看到,JobToBeExecuted和JobWasExecuted都被執(zhí)行了,JobExecutionVetoed沒有執(zhí)行,那么如何觸發(fā)JobExecutionVetoed呢?請繼續(xù)閱讀TriggerListener的演示。

TriggerListener

TriggerListener可以監(jiān)聽Trigger的執(zhí)行情況,我們通過代碼進(jìn)行演示:

publicclassMyTriggerListener:ITriggerListener

publicstringName{get;}=nameof(MyTriggerListener);

publicTaskTriggerComplete(ITriggertrigger,IJobExecutionContextcontext,SchedulerInstructiontriggerInstructionCode,CancellationTokencancellationToken=default)

returnTask.CompletedTask;

publicTaskTriggerFired(ITriggertrigger,IJobExecutionContextcontext,CancellationTokencancellationToken=default)

returnTask.CompletedTask;

publicTaskTriggerMisfired(ITriggertrigger,CancellationTokencancellationToken=default)

returnTask.CompletedTask;

publicTaskboolVetoJobExecution(ITriggertrigger,IJobExecutionContextcontext,CancellationTokencancellationToken=default)

returnTask.FromResult(true);//返回true表示否決Job繼續(xù)執(zhí)行

}

將MyTriggerListener添加到Scheduler中:

scheduler.ListenerManager.AddTriggerListener(newMyTriggerListener(),GroupMatcherTriggerKey.AnyGroup());

運行代碼可以看到如下效果:

從圖片中可以看到,JobListener中的JobExecutionVetoed被執(zhí)行了。

SchedulerListener

ISchedulerListener提供了Job、Trigger管理的監(jiān)聽,與調(diào)度程序相關(guān)的事件包括:添加作業(yè)/觸發(fā)器,刪除作業(yè)/觸發(fā)器,調(diào)度程序中的嚴(yán)重錯誤,調(diào)度程序關(guān)閉的通知等。完整的接口定義如下:

publicinterfaceISchedulerListener

TaskJobAdded(IJobDetailjobDetail,CancellationTokencancellationToken=default);

TaskJobDeleted(JobKeyjobKey,CancellationTokencancellationToken=default);

TaskJobInterrupted(JobKeyjobKey,CancellationTokencancellationToken=default);

TaskJobPaused(JobKeyjobKey,CancellationTokencancellationToken=default);

TaskJobResumed(JobKeyjobKey,CancellationTokencancellationToken=default);

TaskJobScheduled(ITriggertrigger,CancellationTokencancellationToken=default);

TaskJobsPaused(stringjobGroup,CancellationTokencancellationToken=default);

TaskJobsResumed(stringjobGroup,CancellationTokencancellationToken=default);

TaskJobUnscheduled(TriggerKeytriggerKey,CancellationTokencancellationToken=default);

TaskSchedulerError(stringmsg,SchedulerExceptioncause,CancellationTokencancellationToken=default);

TaskSchedulerInStandbyMode(CancellationTokencancellationToken=default);

TaskSchedulerShutdown(CancellationTokencancellationToken=default);

TaskSchedulerShuttingdown(CancellationTokencancellationToken=default);

TaskSchedulerStarted(CancellationTokencancellationToken=default);

TaskSchedulerStarting(CancellationTokencancellationToken=default);

TaskSchedulingDataCleared(CancellationTokencancellationToken=default);

TaskTriggerFinalized(ITriggertrigger,CancellationTokencancellationToken=default);

TaskTriggerPaused(TriggerKeytriggerKey,CancellationTokencancellationToken=default);

TaskTriggerResumed(TriggerKeytriggerKey,CancellationTokencancellationToken=default);

TaskTriggersPaused(stringtriggerGroup,CancellationTokencancellationToken=default);

TaskTriggersResumed(stringtriggerGroup,CancellationTokencancellationToken=default);

}

添加SchedulerListener的代碼如下:

scheduler.ListenerManager.AddSchedulerListener(mySchedListener);

持久化:JobStore

Quartz.Net支持Job的持久化操作,被稱為JobStore。默認(rèn)情況下,Quartz將數(shù)據(jù)持久化到內(nèi)存中,好處是內(nèi)存的速度很快,壞處是無法提供負(fù)載均衡的支持,并且在程序崩潰后,我們將丟失所有Job數(shù)據(jù),對于企業(yè)級系統(tǒng)來說,壞處明顯大于好處,因此有必要將數(shù)據(jù)存儲在數(shù)據(jù)庫中。

ADO.NET存儲

Quartz使用ADO.NET訪問數(shù)據(jù)庫,支持的數(shù)據(jù)庫廠商非常廣泛:

SqlServer-.NETFramework2.0的S

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論