Quartz.NET 作業(yè)調(diào)度(二):Job

JobBuilder

Create

通過 JobBuilder 的 Create 方法,指定一個作業(yè)任務(wù)(一個實現(xiàn)了 IJob 接口的 Job 類)。IJob 接口只有一個 Execute 方法,我們需要在 Execute 方法中完善我們要執(zhí)行的業(yè)務(wù)代碼。

IJobDetail job = JobBuilder.Create<HelloJob>()
                .Build();
public class HelloJob : IJob
{
  public async Task Execute(IJobExecutionContext context)
  {
    await Console.Out.WriteLineAsync("Hi,everybody");
  }
}

Execute 方法中的 context 參數(shù)包含作業(yè)執(zhí)行的所有上下文信息,我們可以通過 context 中的一些屬性獲取需要的數(shù)據(jù)。如:

context.Scheduler 調(diào)度器信息
context.Trigger 觸發(fā)器信息
context.JobDetail 作業(yè)信息
context.ScheduledFireTimeUtc 當前觸發(fā)時間
context.NextFireTimeUtc 下一次將被觸發(fā)時間
......

Identity

Job 注冊到 Quartz 調(diào)度器的時候需要設(shè)置一個標識的 name,同時可以為 name 設(shè)置一個組,方便我們對 Job 分類,在同一個組內(nèi)的 name 必須是唯一的。如果沒有指定,name會自動生成,group 為 DEFAULT。

IJobDetail job = JobBuilder.Create<HelloJob>()
                .WithIdentity("job1", "jobGroup1");
                .Build();

UsingJobData

通過 JobBuilder 的 UsingJobData 方法我們可以為這個 Job 設(shè)置一些附屬信息,當 Job 被執(zhí)行的時候,我們在 Execute 方法中通過 context.JobDetail.JobDataMap 獲取這些信息以供業(yè)務(wù)代碼使用,也可以通過定義同名的屬性,它將會自動注入到屬性值。

var jobDataMap = new JobDataMap();
jobDataMap.Add("name", "beck");

IJobDetail job = JobBuilder.Create<HelloJob>()
                .WithIdentity("job1", "jobGroup1");
                .UsingJobData(jobDataMap)
                .Build();
public class HelloJob : IJob
{
  // 映射JobDetail.JobDataMap的name
  public string Name { get; set; }
  public async Task Execute(IJobExecutionContext context)
  {
    //var name = context.JobDetail.JobDataMap["name"].ToString();
    await Console.Out.WriteLineAsync($"Hi {Name}");
  }
}

注意:Job 和 Trigger 中都可以通過 UsingJobData 來設(shè)置附屬信息,在 Execute 方法中,context.MergedJobDataMap 屬性中既包含 Job 的 DataMap,也包含 Trigger 的 DataMap。當存在同名的參數(shù)時,Trigger 會覆蓋 Job 的參數(shù)值。

StoreDurably

默認情況下,當 Job 沒有對應(yīng)的 Trigger 時,Job 是不能直接被加入調(diào)度器中的,或者在 Trigger 過期之后, 沒有關(guān)聯(lián) Trigger 的 Job 也會被刪除。我們可以通過 JobBuilder 的 StoreDurably 使 Job 獨立存儲于調(diào)度器中。

IJobDetail job = JobBuilder.Create<HelloJob>()
                .WithIdentity("job1", "jobGroup1")
                .UsingJobData(jobDataMap)
                .StoreDurably()
                .Build();

Job

State

Job 默認是無狀態(tài)的,每次執(zhí)行 Job ,context.JobDetail 獲取到值都是原始數(shù)據(jù),對其的任何修改都不會生效。
如:我們試圖修改 JobDataMap 中的 times 屬性,希望每次執(zhí)行后都加1。

var jobDataMap = new JobDataMap();
jobDataMap.Add("times", 1);
public class HelloJob : IJob
{
  public int Times { get; set; }
  public async Task Execute(IJobExecutionContext context)
  {
    context.JobDetail.JobDataMap["times"] = Times + 1;
    await Console.Out.WriteLineAsync($"execute {Times} times");
  }
}
無狀態(tài)的結(jié)果

實際并不會有效,Job 注冊之后,調(diào)度器內(nèi)保存了這個對象,默認情況下是每次通過反射new一個新實例來執(zhí)行的,所以每次修改必然不會有效。但我們可以通過在 Job 類上加上 PersistJobDataAfterExecution Attribute,就可以非常簡單的把 Job 變成有狀態(tài)。

[PersistJobDataAfterExecution]
public class HelloJob : IJob
{
  // ...
}
有狀態(tài)的結(jié)果

Concurrency

當多個 Trigger 同時觸發(fā)一個 Job 或者 一個 Job 執(zhí)行較長,Trigger 條件已經(jīng)被多次觸發(fā),這種情況下,Job 就出現(xiàn)了并發(fā)問題。在并發(fā)情況下,數(shù)據(jù)的準確性必然會有影響。

我們設(shè)置 Trigger 觸發(fā)周期為1s一次,在 Job 的 Exceute 方法中加入代碼:

Thread.Sleep(2000);
并發(fā)的結(jié)果

很明顯結(jié)果的錯誤的,但這時我們可以通過在 Job 類上加上 DisallowConcurrentExecution Attribute,就可以完美解決并發(fā)問題。

[DisallowConcurrentExecution]
public class HelloJob : IJob
{
  // ...
}
無并發(fā)的結(jié)果

參考鏈接:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概述 了解Quartz體系結(jié)構(gòu) Quartz對任務(wù)調(diào)度的領(lǐng)域問題進行了高度的抽象,提出了調(diào)度器、任務(wù)和觸發(fā)器這3個...
    張晨輝Allen閱讀 2,310評論 2 11
  • 入門簡介: 基本上任何公司都會用到調(diào)度這個功能, 比如我們公司需要定期執(zhí)行調(diào)度生成報表, 或者比如博客什么的定時更...
    水車閱讀 6,964評論 0 11
  • Quartz是一個完全由java編寫的功能豐富的開源作業(yè)調(diào)度庫,可以集成到幾乎任何Java應(yīng)用程序中,小到獨立應(yīng)用...
    ProteanBear閱讀 7,308評論 3 24
  • 1.引言 Quartz是一個開源的任務(wù)調(diào)度框架?;诙〞r、定期的策略來執(zhí)行任務(wù)是它的核心功能,比如2018年除夕夜...
    木子道閱讀 2,503評論 0 1
  • 夜深了, 你還未眠, 在想什么呢? 不如早點歇息, 那才是走向未來的你自己……
    小劇在成長閱讀 219評論 2 5

友情鏈接更多精彩內(nèi)容