2011-09-30 166 views
1

我有用C#編寫的服務。服務是全天候活動,但一個線程通過Thread.Sleep睡眠,直到預定時間 - 通常是晚上9點 - 晚上11點 - 執行一些內務處理任務。首次服務開始時,它會計算時間跨度,直到管理時間爲止,並使用該時間跨度調用Thread.Sleep。下一次該線程簡單地調用Thread.Sleep(24 * 60 * 60 * 1000)24小時睡眠。爲什麼Thread.Sleep長時間不精確?

它工作得很好,除了單一安裝當幾分鐘提前睡覺 - 根據跟蹤日誌提前5-8分鐘。幾個星期之後,家政服務時間會轉移幾個小時。我可以期待家務時間可以向前移動 - 而不是倒退。想知道是否有人可以有解釋。我必須承認,我不是在尋找解決問題的不同解決方案 - 只是試圖解釋這種行爲。

+3

是系統時鐘本身的那臺機器上漂流? –

+7

不要使用睡眠。 –

+0

也許系統時鐘正在重置某處?對於調試,您可以讓另一個線程每10分鐘打印一條日誌行 –

回答

10

的Thread.Sleep不適合長期準確睡覺。你應該使用諸如System.Threading.Timer之類的東西。你可以給它一個午夜的第一次運行時間,並讓它每24小時關閉一次。 Timer(TimerCallback, Object, TimeSpan, TimeSpan)構造函數正是你正在尋找的。

+1

睡眠定義是否準確?令我擔憂的是,這種重大漂移只發生在一臺服務器上。數百臺服務器都很好。我擔心該機器上可能會影響其他解決方案的事情。但是什麼? – alecd4

4

睡眠不使用掛鐘時間計算。它使用普通的中斷間隔,大約每隔10ms(可調整和操作系統版本相關)進行。其用於這些中斷時間源是其歷史上被用於一些其他功能的廉價的石英,因此,其頻率是兩個不完全的1/10毫秒和從一臺機器波動到另一個。

正確的方法來解決你的問題是睡眠的時間更短的週期和檢查,如果時間已經到了醒來真實的。

而且,這裏的希望,當你說你正在使用睡眠(),其實你在等待一個超時的事件。就像你正在做

+2

我會說「正確的做法」是使用一個計時器,但這可能只是我;-)否則+1。 – 2011-09-30 06:28:47

+0

@pst:謝謝:)計時器是正確的,但它只在.NET上可用。上述方法是可移植的,可以在任何平臺上工作。實際上,我不會驚訝地發現這也是Timer的實現方式(我不知道) – Rom

相關問題