2009-02-01 55 views
1

我想要一種能夠安排回調的方法,我希望能夠在不同的時間向「計劃程序」對象註冊許多不同的回調。像這樣的東西。安排代表電話

public class Foo 
{ 
    public void Bar() 
    { 
     Scheduler s = new Scheduler(); 
     s.Schedule(() => Debug.WriteLine("Hello in an hour!"), DateTime.Now.AddHours(1)); 
     s.Schedule(() => Debug.WriteLine("Hello a week later!"), DateTime.Now.AddDays(7)); 
    } 
} 

我能想出的實施計劃,最好的辦法是在給定的時間間隔內運行的每個間隔結束時我檢查已註冊的回調,看看它的時間打電話給他們一個計時器,如果是這樣的話。這很簡單,但缺點是隻能得到定時器的「分辨率」。假設定時器設置爲每秒一次,並且註冊一個半秒鐘內調用的回調函數,它仍然可能不會被調用一整秒。

有沒有更好的方法來解決這個問題?

回答

2

這是一個很好的方法。一旦下一個事件發生,您應該動態設置定時器關閉。您可以通過將作業放入優先隊列來完成此任務。畢竟,在任何情況下你都是總是限制在系統可以提供的分辨率,但是你應該編碼,以便它只是只有的限制因素。

+0

我發誓我想到這個解決方案,我點擊發送按鈕的問題。很高興知道這是正確的方法。 – 2009-02-01 20:08:47

1

一個很好的方法是改變你的計時器的持續時間:告訴它在你的第一個/下一個預定事件到期時(但不是在)之前關閉。

<有關不Windows中的實時操作系統,因此它的定時器必須始終都有點不準確>

1

你只有真正需要的調度時earlest醒來,執行什麼標準免責聲明清單上的項目應到期。之後,您將設置計時器,以便下次喚醒計劃程序。

添加新項目時,只需將其時間表與當前正在等待的項目進行比較即可。如果它早些時候取消當前計時器並將新項目設置爲下一個計劃項目。

0

下面是我寫的一個類,使用.NET的內置Timer類來完成這個任務。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 

namespace Sample 
{ 
    /// <summary> 
    /// Use to run a cron job on a timer 
    /// </summary> 
    public class CronJob 
    { 
     private VoidHandler cronJobDelegate; 
     private DateTime? start; 
     private TimeSpan startTimeSpan; 
     private TimeSpan Interval { get; set; } 

     private Timer timer; 

     /// <summary> 
     /// Constructor for a cron job 
     /// </summary> 
     /// <param name="cronJobDelegate">The delegate that will perform the task</param> 
     /// <param name="start">When the cron job will start. If null, defaults to now</param> 
     /// <param name="interval">How long between each execution of the task</param> 
     public CronJob(VoidHandler cronJobDelegate, DateTime? start, TimeSpan interval) 
     { 
      if (cronJobDelegate == null) 
      { 
       throw new ArgumentNullException("Cron job delegate cannot be null"); 
      } 

      this.cronJobDelegate = cronJobDelegate; 
      this.Interval = interval; 

      this.start = start; 
      this.startTimeSpan = DateTime.Now.Subtract(this.start ?? DateTime.Now); 

      this.timer = new Timer(TimerElapsed, this, Timeout.Infinite, Timeout.Infinite); 
     } 

     /// <summary> 
     /// Start the cron job 
     /// </summary> 
     public void Start() 
     { 
      this.timer.Change(this.startTimeSpan, this.Interval); 
     } 

     /// <summary> 
     /// Stop the cron job 
     /// </summary> 
     public void Stop() 
     { 
      this.timer.Change(Timeout.Infinite, Timeout.Infinite); 
     } 

     protected static void TimerElapsed(object state) 
     { 
      CronJob cronJob = (CronJob) state; 
      cronJob.cronJobDelegate.Invoke(); 
     } 
    } 
} 
+0

感謝分享。雖然它不是我正在尋找的東西,因爲我想用一個實例安排多個回調,所以非常高興看看您的代碼以獲取靈感。 – 2009-02-01 20:18:37

0

Quartz.Net作業調度程序。然而,這是安排班級而不是代表。