2014-09-19 101 views
2

後重新啓動INTERVALL我有一個項目,我用TopShelfTopShelf.Quartz如何強制quartz.net作業完成

this example我建設我的工作與

   s.ScheduleQuartzJob(q => 
        q.WithJob(() => JobBuilder.Create<MyJob>().Build()) 
        .AddTrigger(() => TriggerBuilder.Create() 
         .WithSimpleSchedule(builder => builder 
          .WithIntervalInSeconds(5) 
          .RepeatForever()) 
         .Build()) 
       ); 

這觸發我的工作即使前一次仍在運行,每五秒鐘一次。我真正想做的是開始一項工作,完成後等待五秒鐘,然後重新開始。這是可能的還是我必須實現我自己的邏輯(例如通過一個靜態變量)。

回答

2

JobListener解決方案是一種強大且靈活的方式,可在完成後重新安排工作。感謝Nate Kerkhofs和stuartd的意見。

在我來說,因爲我沒有我的工作,不同的情況下,它足以來裝飾我的工作類與DisallowConcurrentExecution屬性

[DisallowConcurrentExecution] 
public class MyJob : IJob 
{ 
} 

FYI:使用JobListerener與TopShelf.Quartz的代碼看起來是這樣的

var jobName = "MyJob"; 
var jobKey = new JobKey(jobName); 

s.ScheduleQuartzJob(q => 
      q.WithJob(() => JobBuilder.Create<MyJob>() 
       .WithIdentity(jobKey).Build()) 
      .AddTrigger(() => TriggerBuilder.Create() 
       .WithSimpleSchedule(builder => builder 
        .WithIntervalInSeconds(5) 
       .Build()) 

var listener = new RepeatAfterCompletionJobListener(TimeSpan.FromSeconds(5)); 
var listenerManager = ScheduleJobServiceConfiguratorExtensions 
     .SchedulerFactory().ListenerManager; 
listenerManager.AddJobListener(listener, KeyMatcher<JobKey>.KeyEquals(jobKey)); 

如果您正在使用TopShelf.Quartz.Ninject(像我一樣),不要忘了打電話之前UseQuartzNinject()調用ScheduleJobServiceConfiguratorExtensions.SchedulerFactory()

+0

我想提到DisallowConcurrentExecution作爲一種可能的解決方案,但你的問題是「*完成後*等待5秒鐘,然後重新開始」。 – stuartd 2014-09-23 13:53:34

+0

是的,我的解釋有點誤導。我的工作可以在零秒和一分鐘之間運行(取決於要處理的數據量)。使用'DisallowConcurrentExecution',我的作業每五秒執行一次,或者在執行後立即執行超過五秒鐘。在我瞭解這個屬性之前,我認爲最好的解決方案是告訴Quartz在工作完成後開始填充,而不是在解僱工作之後開始填充。對於我來說,屬性方法已經足夠了,但我非常肯定,JobListener方法會派上用場,因爲我打算向我的應用程序添加更多作業。 – 2014-09-23 14:15:48

+0

另請注意,您需要從具體類型'JobBuilder.Create '而不是'JobBuilder.Create '創建作業,以便拾取屬性。 – fearofawhackplanet 2014-10-15 17:23:10

4

提議@NateKerkhofs會的工作,這樣的工作聽衆:

public class RepeatAfterCompletionJobListener : IJobListener 
{ 
    private readonly TimeSpan interval; 

    public RepeatAfterCompletionJobListener(TimeSpan interval) 
    { 
     this.interval = interval; 
    } 

    public void JobExecutionVetoed(IJobExecutionContext context) 
    { 
    } 

    public void JobToBeExecuted(IJobExecutionContext context) 
    { 
    } 

    public void JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException) 
    { 
     string triggerKey = context.JobDetail.Key.Name + ".trigger"; 

     var trigger = TriggerBuilder.Create() 
       .WithIdentity(triggerKey) 
       .StartAt(new DateTimeOffset(DateTime.UtcNow.Add(interval))) 
       .Build(); 

     context.Scheduler.RescheduleJob(new TriggerKey(triggerKey), trigger); 
    } 

    public string Name 
    { 
     get 
     { 
      return "RepeatAfterCompletionJobListener"; 
     } 
    } 
} 

然後將監聽器添加到調度:

var jobKey = "myJobKey"; 
var schedule = new StdSchedulerFactory().GetScheduler(); 
listener = new 
    RepeatAfterCompletionJobListener(TimeSpan.FromSeconds(5)); 

schedule.ListenerManager.AddJobListener 
     (listener, KeyMatcher<JobKey>.KeyEquals(new JobKey(jobKey))); 

var job = JobBuilder.Create(MyJob) 
       .WithIdentity(jobKey) 
       .Build(); 

// Schedule the job to start in 5 seconds to give the service time to initialise 
var trigger = TriggerBuilder.Create() 
       .WithIdentity(CreateTriggerKey(jobKey)) 
       .StartAt(DateTimeOffset.Now.AddSeconds(5)) 
       .Build(); 

schedule.ScheduleJob(job, trigger); 

不幸的是,我不知道如何做到這一點(或者如果它可以完成)與Typshelf.Quartz庫使用的流暢語法,我用TopShelf和常規Quartz.Net。

+1

您實際上創建了一個作業偵聽器而不是觸發器偵聽器,因爲您從IJobListener繼承。我提交了一個編輯。 – Matt 2015-07-05 21:04:12