[英]How do timers in a windows service behave when the system is asleep?
假設我有一個Windows服務,它有一個定時器設置為每6小時運行一次,我希望它每天發射4次。 比方說:0000,0600,1200 1800。 (軍事時間,00:00等)
如果系統在1000點睡覺,在1700點喚醒,會發生什么?
我注意到,當計算機進入睡眠狀態時,它不會觸發OnPause
或OnContinue
方法。
如果有人能夠在上述案例中闡明系統的行為,那將是非常了解的。
干杯,並提前感謝。
正如評論中已經提到的:使用任務調度程序而不是計時器。 有關進一步的討論,請參閱此文
然而,計時器在睡眠期間的表現仍然很有趣。 在您提到的特定情況下,選項2將是觀察到的行為。 計時器將在恢復時觸發,因為它在睡眠期間錯過了一個事件,然后再次從0開始計數。下一次點火將在23:00進行。 這個答案有示例代碼來支持觀察。
如果要檢測系統何時休眠和恢復,請訂閱SystemEvents.PowerModeChanged
事件。 此事件的PowerModeChangedEventArgs
包含一個Mode
,您對Suspend
和Resume
感興趣。
根據我的需要,我最終選擇了一個Windows服務,它將檢查是否以及何時需要執行下一個操作,並將計時器設置為該時間。
Windows服務將在從睡眠狀態恢復時更新該時間。
好處是:
由於我的案例很簡單,所以功能已經在一個單獨的dll中,我沒有任何穩定性或內存泄漏問題(如果我這樣做,我會感到羞恥)。 這樣可以保持我每天需要的一次,或者每次計算機喚醒時保持一次,並且不會在系統上產生額外的開銷。
就像Henrik回復和鏈接一樣,正確的答案是2號。
我在linqpad中寫了以下內容,類似於上面答案中的鏈接:
static int counter = 0;
static System.Timers.Timer my_timer;
void Main()
{
// Set up a timer to trigger every minute.
my_timer = new System.Timers.Timer();
DateTime now = DateTime.Now;
my_timer.Interval = (60 - now.Second) * 1000; // Fire at beginning of minute
string.Format("First tick in {0} seconds", my_timer.Interval/1000).Dump();
my_timer.Elapsed += OnTimer;
my_timer.Start();
while (counter < 5) { // sleep away until 5 ticks happen
Thread.Sleep(5000);
}
// stop timer and say goodbye
my_timer.Stop();
DateTime.Now.Dump("Finished running, shutting down");
}
// Print time and counter every timer tick
void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
{
if (my_timer.Interval != 60000) // set to one minute after first time
my_timer.Interval = 60000;
DateTime.Now.ToString("HH:mm:ss.fff").Dump("On Timer fired:");
(counter++).Dump("Static counter :");
}
獲得結果:
首先打勾:37秒
On Timer被解雇:08:47:00.552
靜態計數器:0On Timer被解雇:08:48:00.557
靜態計數器:1On Timer被解雇:08:49:00.571
靜態計數器:2//在08:49:30關閉電腦3分鍾
On Timer被解雇:08:52:33.509
靜態計數器:3On Timer被解雇:08:53:33.510
靜態計數器:4完成運行,關閉1/09/2014 8:53:38 AM
因此,顯然計算機知道它錯過了一個滴答聲,它會觸發該方法一次,並從那里繼續。 請注意,它只會觸發一次。
但如果有人知道幕后發生的事情可以為此提供更多信息,那將會很高興。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.