簡介:定時器一般用作「固定時間間隔」執(zhí)行某個「任務(wù)」。
兩種情況:
「固定時間間隔」執(zhí)行某個「不耗時」任務(wù)
? ? 例:1s 為間隔,執(zhí)行一個耗時在 1s 內(nèi)的任務(wù)。本篇不說明此種情況,這是大眾都能理解的。
「固定時間間隔」執(zhí)行某個「耗時」任務(wù)
? ? 例:1s 為間隔,執(zhí)行一個耗時超過 1s 的任務(wù)。如,定時取內(nèi)存數(shù)據(jù)存入數(shù)據(jù)庫。
接下來是 C# 中涉及的三種定時器,本篇主要想說明上面第二種情況,以 1s 為間隔,執(zhí)行一個耗時2s 的任務(wù)
① System.Timers.Timer


使用 System.Timers.Timer會發(fā)現(xiàn)定時器并沒有受「2s任務(wù)耗時」影響,依舊是1s執(zhí)行一次
② System.Windows.Forms.Timer


使用 System.Windows.Forms.Timer? 會發(fā)現(xiàn)定時器是2s執(zhí)行一次
③ System.Threading.Timer


使用 System.Threading.Timer 會發(fā)現(xiàn)定時器也并沒有受「2s任務(wù)耗時」影響,依舊是1s執(zhí)行一次
當(dāng)需要使用「System.Timers.Timer」和「System.Threading.Timer」按時間順序定時執(zhí)行某些耗時操作時,這里就會存在問題,當(dāng)執(zhí)行耗時操作過程中,定時器會多次觸發(fā),事實上這不是我們想看到的。下面一個小技巧解決這個問題。
第一個能想到是:加一把鎖不就好了,代碼如下

確實,這樣做能夠?qū)崿F(xiàn)「按時間順序定時執(zhí)行某些耗時操作」,但存在一個問題,由于每秒都會出發(fā)定時器,所以會有大量「待執(zhí)行」被阻塞在 lock (obj) 這里,這是劃不來這種代碼短時間內(nèi)看出不出「厲害關(guān)系」,但長時間執(zhí)行一定是一個大坑。
下面一個小技巧完美解決上邊的問題:讓被阻塞的線程直接返回

最終結(jié)果:
