在上一篇中介紹了簡單的利用Quartz執行定時任務
這一次介紹Quartz傳遞參數
比如 執行的任務中,傳給指定人的時候需要帶一些特定的參數,例如個人的姓名等。
方法一、聲明作業的時候攜帶參數
IJobDetail job=JobBuilder.Create<SendMessageJob>() .WithIdentity("sendMessageJob", "group1") //分組 .WithDescription("this is message job") //作業描述 .Build(); //傳遞參數 job.JobDataMap.Add("Student", "張三"); job.JobDataMap.Add("Year", DateTime.Now.Year);
任務方法中:
string stu1 = context.JobDetail.JobDataMap.GetString("Student");
方法二、在聲明策略時攜帶參數
ITrigger trigger=TriggerBuilder.Create() .WithIdentity("sendMessageJob", "group1") //分組 // .StartNow() //馬上執行一次 .WithSimpleSchedule(w => w.WithIntervalInSeconds(5).WithRepeatCount(3)) //沒5秒重復一次。最多重復4次 .Build(); trigger.JobDataMap.Add("Year", DateTime.Now.Year+1);
任務方法中讀取:
int year = context.Trigger.JobDataMap.GetInt("Year");
方法三、使用MergedJobDataMap
需要在策略或者作業中聲明好參數
然后在任務方法中讀取:
int year2 = context.MergedJobDataMap.GetInt("Year");
需要注意的是這個方法會覆蓋參數,也就是假如trigger和JobDetail聲明同名參數的時候,他會默認取后面的值。
比如上面兩個方法都聲明了Year,用此方法的話他會取下面的值,也就是DateTime.Now.Year+1。
假如想讓上一次執行的結果作為下一次執行的參數??
在我們聲明的SendMessageJob里,它繼承於IJob,當它每次執行的時候都會重新調用構造函數,重新拉值,也就是說它本身是一個無狀態的類。
那么想讓上一次的值保留,就必須要他持久化。
那么可以在SendMessageJob這個類上面聲明[PersistJobDataAfterExecution]。它表示每次執行后都會持久化數據
[PersistJobDataAfterExecution] public class SendMessageJob : IJob
我聲明的Year參數
int year = context.JobDetail.JobDataMap.GetInt("Year");
在任務的結尾加上
context.JobDetail.JobDataMap.Put("Year", year + 1);
也就是下次獲取的Year值是這一次的加1
實際結果發現,后幾次不再獲取JobDetail聲明的當前年,而是依次在前一年基礎上加1年
但是有問題就是加入我任務執行的時間間隔超過了我重復的時間間隔。比如原定於每3秒重復一次,結果任務便執行了5秒。
實踐后發現,后一次的結果並非都和預想的一樣。比如上面實例,按道理來說應該是每次年份加1,我讓任務休眠5秒,使得后一次的結果獲取不到前面的值導致錯亂。
這種情況下,需要保證任務每次都執行完畢再開始下一次任務。並不是強制按照聲明的策略,而是看任務完畢與否。
可以在SendMessageJob上聲明[DisallowConcurrentExecution]。
它表示不允許當前執行,必須等上一次任務執行完才可以
使用這個標簽之后,年份得到了正確的值。時間間隔也並非按照聲明的每3秒,而是換成了5秒。