2011-08-23 113 views
0

我創建了一個帶有定時器的Windows服務,其中需要設置每個Elapsed定時器事件之後的時間間隔。例如,我希望它每小時都在一小時內開火。Windows服務中的計時器需要重新啓動

在Program.cs的:

namespace LabelLoaderService 
{ 
    static class Program 
    { 
     /// <summary> 
     /// The main entry point for the application. 
     /// </summary> 
     /// 
     static void Main() 
     { 
#if (!DEBUG) 
      ServiceBase[] ServicesToRun; 
      ServicesToRun = new ServiceBase[] 
      { 
       new LabelLoader() 
      }; 
      ServiceBase.Run(ServicesToRun); 
#else 
      LabelLoader ll = new LabelLoader(); 
      ll.Start(); 
#endif 

     } 
    } 
} 

在LabelLoader.cs:

namespace LabelLoaderService 
{ 
    public partial class LabelLoader : ServiceBase 
    { 
     System.Timers.Timer timer = new System.Timers.Timer(); 

    public LabelLoader() 
    { 
     InitializeComponent(); 
     timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); 
    } 

    protected override void OnStart(string[] args) 
    { 
     SetTimer(); 
    } 


    public void Start() 
    { 
     // Debug Startup    
     SetTimer(); 
    } 


    public void SetTimer() 
    { 
     DateTime nextRunTime = GetNextRunTime(); 
     var ts = nextRunTime - DateTime.Now; 
     timer.Interval = ts.TotalMilliseconds; 
     timer.AutoReset = true; // tried both true & false 
     timer.Enabled = true; 
     GC.KeepAlive(timer); // test - no effect with/without this line 
    } 

    void timer_Elapsed(object source, ElapsedEventArgs e) 
    { 
     timer.Enabled = false; 
     // do some work here 
     SetTimer(); 
    } 

如果我installutil這個在我的本地機器,它正確地確定下一個運行時間和執行。但之後它不會運行。如果我重新啓動服務,它將運行下一個預定時間,然後再次不再。在我的處理結束時調用SetTimer()是否存在重置Interval並設置timer.Start()的問題?

+0

你應該說timer.Start(); –

+0

事件之間的時間有多長?你有沒有嘗試過500ms之類的東西?我問,因爲在控制檯應用程序中使用具有1000毫秒「間隔」的代碼對我來說工作得很好。 – dlev

+0

它根據從配置文件中讀取的內容而變化。現在我把它設置爲每小時一小時。我重新啓動它,並按預期在一小時內再次運行。然後我記錄了下一次運行時間並將其正確計算到下一個小時。但是當它到達那裏時什麼都沒有發生 – Blaze

回答

2

使用System.Threading.Timer代替 - 在我的經驗更適合於服務器一樣使用...

編輯 - 按註釋一些代碼/提示:

下面是一個非常基本的辦法避免再入(應在此特定情況下工作正常) - 更好的將是一些lock/Mutex或類似
使nextRunTime實例字段
創建/與啓動時間例如

// first the TimerCallback, second the parameter (see AnyParam), then the time to start the first run, then the interval for the rest of the runs 
timer = new System.Threading.Timer(new TimerCallback(this.MyTimerHandler), null, 60000, 30000); 


創建類似的定時器處理程序

void MyTimerHandler (object AnyParam) 
{ 
if (nextRunTime > DateTime.Now) 
    return; 

nextRunTime = DateTime.MaxValue; 
// Do your stuff here 
// when finished do 
nextRunTime = GetNextRunTime(); 
} 
+0

什麼是使用System.Threading.Timer的等效代碼?我真的很討厭重新開始。 – Blaze

+0

請參閱編輯一些提示... – Yahia

相關問題