2010-05-05 46 views
2

我有一個System.Timer設置,每天凌晨2點觸發一個事件。 如果定時器啓動失敗,我希望定時器 重置爲每15分鐘運行一次,直到該過程成功完成。Interval屬性發生變化時System.Timer的行爲

// this is how the timer is set up. 
// this is working correctly. 

double startTime = milliseconds_of_hour_to_start. 

Timer = new System.Timers.Timer(startTime); 

以下是在成功或失敗事件處理程序時重置計時器的代碼。 注意計時器沒有被停止, 只是Interval屬性被重置。

if (ProcessSuccess) 
{ 
    Timer.Interval = TimeSpan.FromHours(24).TotalMilliseconds; 
} 
else 
{ 
    Timer.Interval = TimeSpan.FromMinutes(15).TotalMilliseconds; 
} 

我的問題是這樣的,如果進程失敗說4次,那麼成功將計時器現在運行在大約3AM? 即在失敗後2AM的原始開始時間提前15分鐘?

+0

對於未來的實現,可能需要查看http://quartznet.sourceforge.net/。我總是喜歡看看現在可以重用的庫,而不是自己寫 – 2010-05-05 10:55:46

回答

2

我鼓勵你download Reflector,你會發現這樣的問題的快速答案。定時器的時間間隔由TimerBase.ChangeTimer()更改。需要採取多種措施來確保間隔更新是安全和準確的。代碼在finally塊中運行,這樣即使是一個ThreadAbortException也不能搞亂它。它獲取鎖(m_lock成員)以確保跨線程序列化訪問。 ChangeTimerNative()調用調用CLR來更新本地計時器。該方法由TimerNative :: CorChangeTimer()實現,它調用ChangeTimerQueueTimer()Windows API函數。即使從Elapsed回調函數中調用,該函數也被記錄爲安全的。長話短說,是的:它有你正在尋找的行爲。但是,要注意不可避免的競爭條件,計時器可能已經過去了,並且使得回調的線程池線程可能已經計劃運行,但是還沒有得到運行的機會。改變定時器後立即獲得回調並非不可能。

相關問題