System.Threading.Timer的使用技巧



轉自:http://www.360doc.com/content/11/0812/11/1039473_139824496.shtml#


System.Threading.Timer timer = null; //注意一定要在方法體外聲明,要不然運行一會會被回收掉不再運行 timer=new System.Threading.Timer(Send, null, 0, 10000); //Send為方法必須為Send(object obj), 0為第一次執行等待時間,10000為每次執行間隔時間 Timer定時器的設計----實例詳解 Posted on 2008-08-21 10:24 停留的風 閱讀(3607) 評論(6) 編輯 收藏 在系統開發過程中經常用到定時器進行定時處理,比如比較常見的郵件群發、實時更新論壇的在線人數、文章數、點擊率等。 很多情況下,我們不能對某一狀態或者某一行為進行實時監控,所以就希望系統能夠實現這一功能。通過多線程技術可以使得定時器的性能更高。 盡管定時器能夠自動處理或者一些批處理操作,但是定時器也給系統帶來一定的安全隱患,特別是當定時進行的操作出現bug時,如果沒有對Exception做出及時的處理,系統資源將會大大的浪費,嚴重的情況下,可能導致系統崩潰。因此,對於定時器的使用一定要慎重,至少要保證定時處理的行為出現異常的可能性很小,並在出現Exception的情況下及時處理。 System.Threading.Timer 是一個非常常用的定時器類,是一個使用回調方法的計時器,而且由線程池線程服務,簡單且對資源要求不高。 public Timer ( TimerCallback callback, Object state, TimeSpan dueTime, TimeSpan period ) 參數 callback 一個 TimerCallback 委托,表示要執行的方法。 state 一個包含回調方法要使用的信息的對象,或者為 空引用(在 Visual Basic 中為 Nothing)。 dueTime TimeSpan,表示在 callback 參數調用它的方法之前延遲的時間量。指定 -1 毫秒以防止啟動計時器。指定零 (0) 以立即啟動計時器。 period 在調用 callback 所引用的方法之間的時間間隔。指定 -1 毫秒可以禁用定期終止。 方法、原理 使用 TimerCallback 委托指定希望 Timer 執行的方法。計時器委托在構造計時器時指定,並且不能更改。此方法不在創建計時器的線程上執行,而是在系統提供的 ThreadPool 線程上執行。 創建計時器時,可以指定在第一次執行方法之前等待的時間量(截止時間)以及此后的執行期間等待的時間量(時間周期)。可以使用 Change 方法更改這些值或禁用計時器。 當不再需要計時器時,請使用 Dispose 方法釋放計時器持有的資源。如果希望在計時器被釋放時接收到信號,請使用接受 WaitHandle 的 Dispose(WaitHandle) 方法重載。計時器已被釋放后,WaitHandle 便終止。 由計時器執行的回調方法應該是可重入的,因為它是在 ThreadPool 線程上調用的。 備注: 在超過 dueTime 以后及此后每隔 period 時間間隔,都會調用一次 callback 參數所指定的委托。 如果 dueTime 為零 (0),則立即調用 callback。如果 dueTime 是 -1 毫秒,則不會調用 callback;計時器將被禁用,但通過調用 Change 方法可以重新啟用計時器。 如果 period 為零 (0) 或 -1 毫秒,而且 dueTime 為正,則只會調用一次 callback;計時器的定期行為將被禁用,但通過使用 Change 方法可以重新啟用該行為。 最簡單的定時器 using System; using System.Threading; public class TestTimer { /// <summary> /// 定時器 /// </summary> private Timer iTimer; /// <summary> /// constructor /// </summary> public TestTimer() { iTimer = new System.Threading.Timer(new TimerCallback(Doing)); iTimer.Change(TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); } /// <summary> /// /// </summary> /// <param name="nObject"></param> public void Doing(object nObject) { //do something } } 一個比較完整的計時器: 下面是我設計的一個簡單實例。在一個問卷調查系統中,每一張問卷都有其終止日期,當到達了終止日期時,需要系統自動將其關閉。這就需要定時器對問卷的狀態和終止日期進行實時監控,及時關閉。這里采用了一個簡單的單件模式來操作、控制定時器。 這里主要的操作包括定時器開始、終止、執行一次。 /// <summary> /// 管理類 /// </summary> public class PaperManager { /// <summary> /// 定時器 /// </summary> private Timer iTimer; /// <summary> /// 啟動時間 /// </summary> private TimeSpan dueTime; /// <summary> /// 方法調用間隔 /// </summary> private TimeSpan period; /// <summary> /// 委托 /// </summary> private TimerCallback timerDelegate; /// <summary> /// 靜態實例 /// </summary> private static readonly PaperManager self = new PaperManager(); /// <summary> /// 構造函數 /// </summary> public PaperManager() { timerDelegate = new TimerCallback(CheckStatus); } /// <summary> /// /// </summary> /// <returns></returns> public static PaperManager getInstance() { return self; } /// <summary> /// 設置啟動時間間隔 /// </summary> /// <param name="days"></param> /// <param name="hours">小時</param> /// <param name="minutes">分鍾</param> /// <param name="seconds"></param> /// <param name="milisecond">毫秒</param> public void setDueTime(int days, int hours, int minutes, int seconds, int milisecond) { dueTime = new TimeSpan(days, hours, minutes, seconds, milisecond); } /// <summary> /// 設置回調時間間隔 /// </summary> /// <param name="days"></param> /// <param name="hours">小時</param> /// <param name="minutes">分鍾</param> /// <param name="seconds"></param> /// <param name="milisecond">毫秒</param> public void setPeriod(int days, int hours, int minutes, int seconds, int milisecond) { period = new TimeSpan(days, hours, minutes, seconds, milisecond); } /// <summary> /// 開始 /// </summary> public void Start() { AutoResetEvent autoEvent = new AutoResetEvent(false); dueTime = TimeSpan.FromSeconds(0); period = TimeSpan.FromSeconds(10); iTimer = new Timer(timerDelegate, autoEvent, dueTime, period); autoEvent.WaitOne(5000, false); iTimer.Change(dueTime, period); } /// <summary> /// 停止 /// </summary> public void Stop() { iTimer.Dispose(); } /// <summary> /// 執行一次 /// </summary> public void ExcuteOneTime() { if (iTimer != null) { iTimer.Dispose(); } //如果 period 為零 (0) 或 -1 毫秒,而且 dueTime 為正,則只會調用一次 callback; //計時器的定期行為將被禁用,但通過使用 Change 方法可以重新啟用該行為。 setDueTime(0, 0, 0, 0, 1); setPeriod(0, 0, 0, 0, -1); AutoResetEvent autoEvent = new AutoResetEvent(false); iTimer = new Timer(timerDelegate, autoEvent, dueTime, period); autoEvent.WaitOne(5000, false); iTimer.Change(dueTime, period); } /// <summary> /// 行為 /// </summary> /// <param name="nObject"></param> public void CheckStatus(object nObject) { AutoResetEvent autoEvent = (AutoResetEvent)nObject; if (ExcuteUpdate()) { autoEvent.Set(); } } /// <summary> /// 更新 /// </summary> /// <returns></returns> private bool ExcuteUpdate() { try { //應該從數據庫獲得Paper對象的集合,這里簡略 //List<Paper> paperList = getPaperList(); List<Paper> paperList = new List<Paper>(); foreach (Paper item in paperList) { if (item.EndTime <= DateTime.Now) { if (item.Status == Paper.StatusOfNormal) { item.Status = Paper.StatusOfTerminate; } } } ////執行數據更新,這里省略 return true; } catch { return false; } } } 這是問卷的實體類,只是簡單的列出必要的屬性。 /// <summary> /// 實體類 /// </summary> public class Paper { /// <summary> /// 終止時間 /// </summary> public DateTime EndTime; /// <summary> /// 狀態 /// </summary> public int Status; /// <summary> /// 正常 /// </summary> public const int StatusOfNormal = 1; /// <summary> /// 終止 /// </summary> public const int StatusOfTerminate = 2; /// <summary> /// /// </summary> /// <param name="status"></param> /// <param name="endTime"></param> public Paper(int status, DateTime endTime) { Status = status; EndTime = endTime; } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM