1. 程式人生 > >quartznet任務排程和訊息排程(JAVA與C#版對比)

quartznet任務排程和訊息排程(JAVA與C#版對比)

quartznet任務排程和訊息排程

1.  作用

自動執行任務。

2.  下載地址

NET版本

JAVA版本

1下載

http://quartznet.sourceforge.net/download.html

http://opensymphony.com/quartz

2工具

Visual Studio2008/2010開啟

3概念

排程器和作業

排程器、任務和觸發器

1)  作業

是一個執行任務的簡單.NET類。任務可以是任何C#\VB.NET

程式碼。只需你實現Quartz.IJob介面並且在出現嚴重錯誤情況下丟擲JobExecutionException異常即可。

IJob介面包含唯一的一個方法Execute()

排程器負責管理Quartz.NET應用執行時環境。排程器不是靠自己做所有的工作,而是依賴框架內一些非常重要的部件。Quartz不僅僅是執行緒和執行緒管理。為確保可伸縮性,Quartz.NET採用了基於多執行緒的架構。啟動時,框架初始化一套worker執行緒,這套執行緒被排程器用來執行預定的作業。這就是Quartz.NET怎樣能併發執行多個作業的原理。Quartz.NET依賴一套鬆耦合的執行緒池管理部件來管理執行緒環境。

1Job:是一個介面,只有一個方法void execute(JobExecutionContext context),開發者實現該介面定義執行任務,JobExecutionContext類提供了排程上下文的各種資訊。Job執行時的資訊儲存在JobDataMap例項中;

2JobDetailQuartz在每次執行Job時,都重新建立一個Job例項,所以它不直接接受一個Job的例項,相反它接收一個Job實現類,以便執行時通過newInstance()的反射機制例項化Job。因此需要通過一個類來描述Job的實現類及其它相關的靜態資訊,如Job名字、描述、關聯監聽器等資訊,JobDetail

承擔了這一角色。

通過該類的建構函式可以更具體地瞭解它的功用:JobDetail(java.lang.String name, java.lang.String group,  java.lang.Class jobClass),該建構函式要求指定Job的實現類,以及任務在Scheduler中的組名和Job名稱;

3Trigger:是一個類,描述觸發Job執行的時間觸發規則。主要有SimpleTriggerCronTrigger這兩個子類。當僅需觸發一次或者以固定時間間隔週期執行,SimpleTrigger是最適合的選擇;而CronTrigger則可以通過Cron表示式定義出各種複雜時間規則的排程方案:如每早晨9:00執行,週一、週三、週五下午5:00執行等;

4Calendarorg.quartz.Calendarjava.util.Calendar不同,它是一些日曆特定時間點的集合(可以簡單地將org.quartz.Calendar看作java.util.Calendar的集合——java.util.Calendar代表一個日曆時間點,無特殊說明後面的Calendar即指org.quartz.Calendar)。一個Trigger可以和多個Calendar關聯,以便排除或包含某些時間點。

假設,我們安排每週星期一早上10:00執行任務,但是如果碰到法定的節日,任務則不執行,這時就需要在Trigger觸發機制的基礎上使用Calendar進行定點排除。針對不同時間段型別,Quartzorg.quartz.impl.calendar包下提供了若干個Calendar的實現類,如AnnualCalendarMonthlyCalendarWeeklyCalendar分別針對每年、每月和每週進行定義;

5Scheduler代表一個Quartz的獨立執行容器,TriggerJobDetail可以註冊到Scheduler中,兩者在Scheduler中擁有各自的組及名稱,組及名稱是Scheduler查詢定位容器中某一物件的依據,Trigger的組及名稱必須唯一,JobDetail的組和名稱也必須唯一(但可以和Trigger的組和名稱相同,因為它們是不同型別的)。Scheduler定義了多個介面方法,允許外部通過組及名稱訪問和控制容器中TriggerJobDetail

6ThreadPoolScheduler使用一個執行緒池作為任務執行的基礎設施,任務通過共享執行緒池中的執行緒提高執行效率。

作業管理和儲存Quartz通過一個稱之為作業儲存(JobStore)的概念來做作業儲存和管理。

有效作業儲存:

1作業記憶體儲存型別RAMJobStore(預設)

2)資料庫儲存AdoJobStore

  A)支援AdoJobStore幾乎可以在任何資料庫上工作,它廣泛地使用Oracle, MySQL, MS SQLServer2000, HSQLDB, PostreSQL以及 DB2

  B)指令碼在:AdoJobStore幾乎可以在任何資料庫上工作,它廣泛地使用Oracle, MySQL, MS SQLServer2000, HSQLDB, PostreSQL 以及 DB2

C)需要注意的一件事情就是所有Quartz庫表名都以QRTZ_作為字首(例如:表"QRTZ_TRIGGERS","QRTZ_JOB_DETAIL")。實際上,可以你可以將字首設定為任何你想要的字首,只要你告訴AdoJobStore那個字首是什麼即可(在你的Quartz屬性檔案中配置)。對於一個數據庫中使用多個scheduler例項,那麼配置不同的字首可以建立多套庫表,十分有用。

3.  C#應用

Quartz.NET是一個開源的作業排程框架,是OpenSymphony的 Quartz API的.NET移植,它用C#寫成,可用於winform和asp.net應用中。它提供了巨大的靈活性而不犧牲簡單性。你能夠用它來為執行一個作業而建立簡單的或複雜的排程。它有很多特徵,如:資料庫支援,叢集,外掛,支援cron-like表示式等等。

你曾經需要應用執行一個任務嗎?這個任務每天或每週星期二晚上11:30,或許僅僅每個月的最後一天執行。一個自動執行而無須干預的任務在執行過程中如果發生一個嚴重錯誤,應用能夠知到其執行失敗並嘗試重新執行嗎?你和你的團隊是用.NET程式設計嗎?如果這些問題中任何一個你回答是,那麼你應該使用Quartz.NET排程器。 Quartz.NET允許開發人員根據時間間隔(或天)來排程作業。它實現了作業和觸發器的多對多關係,還能把多個作業與不同的觸發器關聯。整合了 Quartz.NET的應用程式可以重用來自不同事件的作業,還可以為一個事件組合多個作業.

Quartz.NET入門

要開始使用 Quartz.NET,需要用 Quartz.NET API 對專案進行配置。步驟如下:

1.http://quartznet.sourceforge.net/download.html下載 Quartz.NET API,最新版本是0.6

2.解壓縮Quartz.NET-0.6.zip到目錄,根據你的專案情況用Visual Studio 2003或者Visual Studio 2005開啟相應工程,編譯。你可以將它放進自己的應用中。Quartz.NET框架只需要少數的第三方庫,並且這些三方庫是必需的,你很可能已經在使用這些庫了。

3.在Quartz.NET有一個叫做quartz.properties的配置檔案,它允許你修改框架執行時環境。預設是使用Quartz.dll裡面的quartz.properties檔案。當然你可以在應用程式配置檔案中做相應的配置,下面是一個配置檔案示例:

<?xml version="1.0"encoding="utf-8"?>

<configuration>

<configSections>

<section name="quartz" type="System.Configuration.NameValueSectionHandler,System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

</configSections>

<quartz>

<add key="quartz.scheduler.instanceName" value="ExampleDefaultQuartzScheduler"/>

<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool,Quartz"/>

<add key="quartz.threadPool.threadCount" value="10"/>

<add key="quartz.threadPool.threadPriority" value="2"/>

<add key="quartz.jobStore.misfireThreshold" value="60000"/>

<add key="quartz.jobStore.type" value="Quartz.Simpl.RAMJobStore,Quartz"/>

</quartz>

</configuration>

為了方便讀者,我們使用Quartz.NET的例子程式碼來解釋,現在來看一下 Quartz API 的主要元件。

排程器和作業

Quartz.NET框架的核心是排程器。排程器負責管理Quartz.NET應用執行時環境。排程器不是靠自己做所有的工作,而是依賴框架內一些非常重要的部件。Quartz不僅僅是執行緒和執行緒管理。為確保可伸縮性,Quartz.NET採用了基於多執行緒的架構。啟動時,框架初始化一套worker執行緒,這套執行緒被排程器用來執行預定的作業。這就是Quartz.NET怎樣能併發執行多個作業的原理。Quartz.NET依賴一套鬆耦合的執行緒池管理部件來管理執行緒環境。作業是一個執行任務的簡單.NET類。任務可以是任何C#\VB.NET程式碼。只需你實現Quartz.IJob介面並且在出現嚴重錯誤情況下丟擲JobExecutionException異常即可。

IJob介面包含唯一的一個方法Execute(),作業從這裡開始執行。一旦實現了IJob介面和Execute ()方法,當Quartz.NET確定該是作業執行的時候,它將呼叫你的作業。Execute()方法內就完全是你要做的事情。

通過實現 Quartz.IJob介面,可以使 .NET 類變成可執行的。清單 1 提供了 Quartz.IJob作業的一個示例。這個類用一條非常簡單的輸出語句覆蓋了 Execute(JobExecutionContext context) 方法。這個方法可以包含我們想要執行的任何程式碼(所有的程式碼示例都基於 Quartz.NET 0.6 ,它是編寫這篇文章時的穩定發行版)。

清單 1:作業

using System;

using System.Collections.Generic;

using System.Text;

using Common.Logging;

using Quartz;

namespace QuartzBeginnerExample

{

publicclass SimpleQuartzJob : IJob

{

privatestatic ILog _log = LogManager.GetLogger(typeof(SimpleQuartzJob));

///<summary>

/// Called by the<seecref="IScheduler" /> whena

///<seecref="Trigger" /> firesthat is associated with

/// the <seecref="IJob" />.

///</summary>

publicvirtualvoid Execute(JobExecutionContext context)

{ try
{

// This job simply prints out its job nameand the

// date and time that it is running

string jobName = context.JobDetail.FullName;

_log.Info("Executing job:" + jobName +" executing at " + DateTime.Now.ToString("r"));

}

catch (Exception e)

{

_log.Info("--- Error injob!");

JobExecutionException e2 = new JobExecutionException(e);

// this job will refire immediately

e2.RefireImmediately = true;throw e2;
}

}

}

}

請注意,Execute方法接受一個 JobExecutionContext 物件作為引數。這個物件提供了作業例項的執行時上下文。特別地,它提供了對排程器和觸發器的訪問,這兩者協作來啟動作業以及作業的 JobDetail 物件的執行。Quartz.NET 通過把作業的狀態放在 JobDetail 物件中並讓 JobDetail 建構函式啟動一個作業的例項,分離了作業的執行和作業周圍的狀態。JobDetail 物件儲存作業的偵聽器、群組、資料對映、描述以及作業的其他屬性。

作業和觸發器:

Quartz.NET設計者做了一個設計選擇來從排程分離開作業。Quartz.NET中的觸發器用來告訴排程程式作業什麼時候觸發。框架提供了一把觸發器型別,但兩個最常用的是SimpleTrigger和CronTrigger。SimpleTrigger為需要簡單打火排程而設計。

典型地,如果你需要在給定的時間和重複次數或者兩次打火之間等待的秒數打火一個作業,那麼SimpleTrigger適合你。另一方面,如果你有許多複雜的作業排程,那麼或許需要CronTrigger。

CronTrigger是基於Calendar-like排程的。當你需要在除星期六和星期天外的每天上午10點半執行作業時,那麼應該使用CronTrigger。正如它的名字所暗示的那樣,CronTrigger是基於Unix克隆表示式的。

Cron表示式被用來配置CronTrigger例項。Cron表示式是一個由7個子表示式組成的字串。每個子表示式都描述了一個單獨的日程細節。這些子表示式用空格分隔,分別表示:

1. Seconds

2. Minutes分鐘

3. Hours小時

4. Day-of-Month月中的天

5. Month

6. Day-of-Week週中的天

7. Year (optional field)年(可選的域)

一個cron表示式的例子字串為"0 0 12 ? * WED",這表示“每週三的中午12:00”。

單個子表示式可以包含範圍或者列表。例如:前面例子中的週中的天這個域(這裡是"WED")可以被替換為"MON-FRI","MON, WED, FRI"或者甚至"MON-WED,SAT"。

萬用字元('*')可以被用來表示域中“每個”可能的值。因此在"Month"域中的*表示每個月,而在Day-Of-Week域中的*則表示“週中的每一天”。

所有的域中的值都有特定的合法範圍,這些值的合法範圍相當明顯,例如:秒和分域的合法值為0到59,小時的合法範圍是0到23,Day-of-Month中值得合法凡範圍是0到31,但是需要注意不同的月份中的天數不同。月份的合法值是0到11。或者用字串JAN,FEBMAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV 及DEC來表示。Days-of-Week可以用1到7來表示(1=星期日)或者用字串SUN, MON, TUE, WED, THU, FRI 和SAT來表示.

'/'字元用來表示值的增量,例如,如果分鐘域中放入'0/15',它表示“每隔15分鐘,從0開始”,如果在份中域中使用'3/20',則表示“小時中每隔20分鐘,從第3分鐘開始”或者另外相同的形式就是'3,23,43'。

'?'字元可以用在day-of-month及day-of-week域中,它用來表示“沒有指定值”。這對於需要指定一個或者兩個域的值而不需要對其他域進行設定來說相當有用。

'L'字元可以在day-of-month及day-of-week中使用,這個字元是"last"的簡寫,但是在兩個域中的意義不同。例如,在day-of-month域中的"L"表示這個月的最後一天,即,一月的31日,非閏年的二月的28日。如果它用在day-of-week中,則表示"7"或者"SAT"。但是如果在day-of-week域中,這個字元跟在別的值後面,則表示"當月的最後的周XXX"。例如:"6L" 或者 "FRIL"都表示本月的最後一個週五。當使用'L'選項時,最重要的是不要指定列表或者值範圍,否則會導致混亂。

'W'字元用來指定距離給定日最接近的周幾(在day-of-week域中指定)。例如:如果你為day-of-month域指定為"15W",則表示“距離月中15號最近的周幾”。

'#'表示表示月中的第幾個周幾。例如:day-of-week域中的"6#3" 或者 "FRI#3"表示“月中第三個週五”。

作為一個例子,下面的Quartz.NET克隆表示式將在星期一到星期五的每天上午10點15分執行一個作業。

0 15 10 ? * MON-FRI

下面的表示式

0 15 10 ? * 6L 2007-2010

將在2007年到2010年的每個月的最後一個星期五上午10點15分執行作業。你不可能用SimpleTrigger來做這些事情。你可以用兩者之中的任何一個,但哪個跟合適則取決於你的排程需要。

清單 2中的 SimpleTrigger 展示了觸發器的基礎:

清單2 SimpleTriggerRunner.cs

using System;using System.Collections.Generic;using System.Text;using Common.Logging;using Quartz; using Quartz.Impl;namespace QuartzBeginnerExample
{
publicclass SimpleTriggerRunner
{

publicvirtualvoid Run()
{

ILog log = LogManager.GetLogger(typeof(SimpleTriggerExample));

log.Info("-------Initializing -------------------");

// First we must get a reference to ascheduler

ISchedulerFactory sf = new StdSchedulerFactory();

IScheduler sched = sf.GetScheduler();

log.Info("-------Initialization Complete --------");

log.Info("-------Scheduling Jobs ----------------");

// jobs can be scheduled beforesched.start() has been called

// get a "nice round" time a few seconds in the future...

DateTime ts = TriggerUtils.GetNextGivenSecondDate(null,15);

// job1 will only fire once at date/time"ts"

JobDetail job = new JobDetail("job1","group1",typeof(SimpleJob));

SimpleTrigger trigger = new SimpleTrigger("trigger1","group1");

// set its start up time

trigger.StartTime = ts; // set the interval, how often the jobshould run (10 seconds here)
trigger.RepeatInterval =
10000;// set the number of execution of thisjob, set to 10 times.
// It will run 10 time and exhaust.

trigger.RepeatCount = 100;// schedule it to run!
DateTime ft = sched.ScheduleJob(job, trigger);

log.Info(
string.Format("{0} will run at: {1} and repeat: {2} times, every{3} seconds",
job.FullName, ft.ToString(
"r"), trigger.RepeatCount,(trigger.RepeatInterval /1000)));
log.Info(
"-------Starting Scheduler ----------------");// All of the jobs have been added to thescheduler, but none of the jobs
// will run until the scheduler has been started

sched.Start();

log.Info(
"-------Started Scheduler -----------------");
log.Info(
"-------Waiting 30 seconds... --------------");try
{
// wait 30 seconds to show jobs
Thread.Sleep(
30 *1000);// executing...
}
catch (ThreadInterruptedException)
{

}

log.Info("-------Shutting Down ---------------------");

sched.Shutdown(true);

log.Info("-------Shutdown Complete -----------------");

// display some stats about the schedulethat just ran

SchedulerMetaData metaData = sched.GetMetaData();

log.Info(string.Format("Executed {0} jobs.", metaData.NumJobsExecuted));

}

}

}

清單 2開始時例項化一個 SchedulerFactory,獲得此排程器。就像前面討論過的,建立 JobDetail 物件時,它的建構函式要接受一個 Job 作為引數。顧名思義,SimpleTrigger 例項相當原始。在建立物件之後,設定幾個基本屬性以立即排程任務,然後每 10 秒重複一次,直到作業被執行 100 次。

還有其他許多方式可以操縱 SimpleTrigger。除了指定重複次數和重複間隔,還可以指定作業在特定日曆時間執行,只需給定執行的最長時間或者優先順序(稍後討論)。執行的最長時間可以覆蓋指定的重複次數,從而確保作業的執行不會超過最長時間。

清單 3顯示了 CronTrigger 的一個示例。請注意 SchedulerFactory、Scheduler 和 JobDetail 的例項化,與 SimpleTrigger 示例中的例項化是相同的。在這個示例中,只是修改了觸發器。這裡指定的 cron 表示式(“0/5 * * * * ?”)安排任務每 5 秒執行一次。

清單3 CronTriggerRunner.cs

using System;using System.Collections.Generic;using System.Text;using Common.Logging;using Quartz;

using Quartz.Impl;using System.Threading;namespace QuartzBeginnerExample
{
publicclass CronTriggerRunner

{

publicvirtualvoid Run()

{

ILog log = LogManager.GetLogger(typeof(CronTriggerRunner));

log.Info("-------Initializing -------------------");

// First we must get a reference to ascheduler

ISchedulerFactory sf = new StdSchedulerFactory();

IScheduler sched = sf.GetScheduler();

log.Info("-------Initialization Complete --------");

log.Info("-------Scheduling Jobs ----------------");

// jobs can be scheduled beforesched.start() has been called

// job 1 will run every 20 seconds

JobDetail job = new JobDetail("job1","group1",typeof(SimpleQuartzJob));

CronTrigger trigger = new CronTrigger("trigger1","group1","job1", "group1");

trigger.CronExpressionString = "0/20* * * * ?";

sched.AddJob(job, true);

DateTime ft = sched.ScheduleJob(trigger);

log.Info(string.Format("{0} has been scheduled to run at: {1} and repeatbased on expression: {2}",job.FullName, ft.ToString("r"), trigger.CronExpressionString));

log.Info("-------Starting Scheduler ----------------");

// All of the jobs have been added to thescheduler, but none of the

// jobs

// will run until the scheduler has been started

sched.Start();

log.Info("-------Started Scheduler -----------------");

log.Info("-------Waiting five minutes... ------------");

try

{

// wait five minutes to show jobs

Thread.Sleep(300 *1000);

// executing...

} catch (ThreadInterruptedException)

{

}

log.Info("-------Shutting Down ---------------------");

sched.Shutdown(true);

log.Info("-------Shutdown Complete -----------------");

SchedulerMetaData metaData = sched.GetMetaData();

log.Info(string.Format("Executed {0} jobs.", metaData.NumJobsExecuted));

}

}

}

如上所示,只用作業和觸發器,就能訪問大量的功能。但是,Quartz是個豐富而靈活的排程包,對於願意研究它的人來說,它還提供了更多功能。下一節討論 Quartz 的一些高階特性。

作業管理和儲存

作業一旦被排程,排程器需要記住並且跟蹤作業和它們的執行次數。如果你的作業是30分鐘後或每30秒呼叫,這不是很有用。事實上,作業執行需要非常準確和即時呼叫在被排程作業上的Execute()方法。Quartz通過一個稱之為作業儲存(JobStore)的概念來做作業儲存和管理。

有效作業儲存

Quartz提供兩種基本作業儲存型別。第一種型別叫做RAMJobStore,它利用通常的記憶體來持久化排程程式資訊。這種作業儲存型別最容易配置、構造和執行。Quartz.net預設使用的就是RAMJobStore。對許多應用來說,這種作業儲存已經足夠了。

然而,因為排程程式資訊是儲存在被分配在記憶體裡面,所以,當應用程式停止執行時,所有排程資訊將被丟失。如果你需要在重新啟動之間持久化排程資訊,則將需要第二種型別的作業儲存。為了修正這個問題,Quartz.NET提供了 AdoJobStore。顧名思義,作業倉庫通過 ADO.NET把所有資料放在資料庫中。資料永續性的代價就是效能降低和複雜性的提高。它將所有的資料通過ADO.NET儲存到資料庫可中。它的配置要比RAMJobStore稍微複雜,同時速度也沒有那麼快。但是效能的缺陷不是非常差,尤其是如果你在資料庫表的主鍵上建立索引。

設定AdoJobStore

AdoJobStore幾乎可以在任何資料庫上工作,它廣泛地使用Oracle, MySQL, MS SQLServer2000, HSQLDB, PostreSQL以及 DB2。要使用AdoJobStore,首先必須建立一套Quartz使用的資料庫表,可以在Quartz 的database\tables找到建立庫表的SQL指令碼。如果沒有找到你的資料庫型別的指令碼,那麼找到一個已有的,修改成為你資料庫所需要的。需要注意的一件事情就是所有Quartz庫表名都以QRTZ_作為字首(例如:表"QRTZ_TRIGGERS",及"QRTZ_JOB_DETAIL")。實際上,可以你可以將字首設定為任何你想要的字首,只要你告訴AdoJobStore那個字首是什麼即可(在你的Quartz屬性檔案中配置)。對於一個數據庫中使用多個scheduler例項,那麼配置不同的字首可以建立多套庫表,十分有用。

一旦資料庫表已經建立,在配置和啟動AdoJobStore之前,就需要作出一個更加重要的決策。你要決定在你的應用中需要什麼型別的事務。如果不想將scheduling命令綁到其他的事務上,那麼你可以通過對JobStore使用JobStoreTX來讓Quartz幫你管理事務(這是最普遍的選擇)。

最後的疑問就是如何建立獲得資料庫聯接的資料來源(DataSource)。Quartz屬性中定義資料來源是通過提供所有聯接資料庫的資訊,讓Quartz自己建立和管理資料來源。

要使用AdoJobStore(假定使用StdSchedulerFactory),首先需要設定Quartz配置中的quartz.jobStore.type屬性為Quartz.Impl.AdoJobStore.JobStoreTX, Quartz。

配置 Quartz使用 JobStoreTx

quartz.threadPool.type = Quartz.Simpl.SimpleThreadPool, Quartz

下一步,需要為JobStore選擇一個DriverDelegate , DriverDelegate負責做指定資料庫的所有ADO.NET工作。StdADO.NETDelegate是一個使用vanilla" ADO.NET程式碼(以及SQL語句)來完成工作的代理。如果資料庫沒有其他指定的代理,那麼就試用這個代理。只有當使用StdADO.NETDelegate發生問題時,我們才會使用資料庫特定的代理(這看起來非常樂觀。其他的代理可以在Quartz.Impl.AdoJobStor名稱空間找到。)。其他的代理包括PostgreSQLDelegate( 專為PostgreSQL 7.x)。

一旦選擇好了代理,就將它的名字設定給AdoJobStore

配置AdoJobStore使用DriverDelegate

quartz.threadPool.type = Quartz.Simpl.SimpleThreadPool, Quartz

接下來,需要為JobStore指定所使用的資料庫表字首(前面討論過)。

配置AdoJobStore的資料庫表字首

quartz.jobStore.tablePrefix = QRTZ

然後需要設定JobStore所使用的資料來源。必須在Quartz屬性中定義已命名的資料來源,比如,我們指定Quartz使用名為"default"的資料來源(在配置檔案的其他地方定義)。

配置 AdoJobStore使用資料來源源的名字

properties["quartz.jobStore.dataSource"] = "default"

最後,需要配置資料來源的使用的Ado.net資料提供者和資料庫連線串,資料庫連線串是標準的Ado.net 資料庫連線的連線串。資料庫提供者是關係資料庫同Quartz.net之間保持低耦合的資料庫的連線提供者.

配置AdoJobStore使用資料來源源的資料庫連線串和資料庫提供者

quartz.dataSource.default.connectionString =Server=(local);Database=quartz;Trusted_Connection=True;

quartz.dataSource.default.provider= SqlServer-11

目前Quartz.net支援的以下資料庫的資料提供者:

l SqlServer-11 - SQL Server driver for .NET Framework 1.1

l SqlServer-20 - SQL Server driver for .NET Framework 2.0

l OracleClient-20 - Microsoft's Oracle Driver (comes bundled with .NETFramework)

l OracleODP-20 - Oracle's Oracle Driver

l MySql-10 - MySQL Connector/.NET v. 1.0.7

l MySql-109 - MySQL Connector/.NET v. 1.0.9

l MySql-50 - MySQL Connector/.NET v. 5.0 (.NET 2.0)

l MySql-51 - MySQL Connector/:NET v. 5.1 (.NET 2.0)

l SQLite1044 - SQLite ADO.NET 2.0 Provider v. 1.0.44 (.NET 2.0)

如果Scheduler非常忙(比如,執行的任務數量差不多和執行緒池的數量相同,那麼你需要正確地配置DataSource的連線數量為執行緒池數量。為了指示AdoJobStore所有的JobDataMaps中的值都是字串,並且能以“名字-值”對的方式儲存而不是以複雜物件的序列化形式儲存在BLOB欄位中,應設定 quartz.jobStore.usePropertiess配置引數的值為"true"(這是預設的方式)。這樣做,從長遠來看非常安全,這樣避免了對儲存在BLOB中的非字串的序列化物件的型別轉換問題。

清單 4展示了 AdoJobStore提供的資料永續性。就像在前面的示例中一樣,先從初始化 SchedulerFactory 和 Scheduler 開始。然後,不再需要初始化作業和觸發器,而是要獲取觸發器群組名稱列表,之後對於每個群組名稱,獲取觸發器名稱列表。請注意,每個現有的作業都應當用 Scheduler. RescheduleJob () 方法重新排程。僅僅重新初始化在先前的應用程式執行時終止的作業,不會正確地裝載觸發器的屬性。

清單4 AdoJobStoreRunner.cs

publicclas