那麽說起定時執行任務,多數碼農一定會知道timer,而且有各種說法。
c#中的三個timer類:
system.Timers.Timer:在一個固定時間間隔觸發並執行code,這個類主要用於服務端或作為服務組件用在多線程環境中,它沒有用戶界面並且運行時不可見。//不推薦,在.NET Framework 5, .NET Core and ASP.NET Core中都已棄用
System.Threading.Timer:在一個線程池中固定時間間隔執行一個回調方法,這個回調方法在實例化時被定義 ,並且不能修改。跟System.Timers.Timerg一樣主要用於服務端或作為服務組件用在多線程環境中,它沒有用戶界面並且運行時不可見。//推薦
System.Windows.Forms.Timer:是一上Windows Forms 的組件,在固定時間間隔觸發一個事件並執行,這個組件沒有用戶界面並且是為單線程設計的.
System.Web.UI.Timer:是一個Asp.NET組件,可以在定期進行異步或同步web頁面回發。
總之呢,先來對這三種Timer實戰一次:
System.Timers.Timer,貼code:
public class TimerTest { private System.Timers.Timer timer = new Timer(); private DateTime dtSwitchJob = null; public TimerTest() { timer.Interval = 1000;//每秒執行一次 timer.Elapsed += t_Elapsed; } public void Start() { timer.Enabled = true; dtSwitchJob = DateTime.Now.AddMinutes(1);//一分鐘後修改執行間隔 } public void Stop() { timer.Enabled = false; } private void t_Elapsed(object sender, ElapsedEventArgs e) { DateTime dtNow = DateTime.Now; if (dtNow.Date == dtSwitchJob.Date && dtNow.Hour == dtSwitchJob.Hour && dtNow.Minute == dtSwitchJob.Minute) { timer.Interval = 60*1000;//一分鐘後設定為每分鐘執行一次 } Console.WriteLine(DateTime.Now); } }
System.Threading.Timer,貼code:
private static System.Threading.Timer timer = null; //new System.Threading.Timer(Run, null, , 2000); public static void Run(object param) { Console.WriteLine("Running" + DateTime.Now); timer.Change(10 * 1000, Timeout.Infinite);//每10秒執行一次guan } public TimerTest() { timer = new System.Threading.Timer(Run, null, 1000, 5000);//1秒後,每隔5秒鐘執行一次 } //下面是Timer帶參數的例子,為了不誤人子弟我直接粘官方了: using System; using System.Threading; class TimerExample { static void Main() { //在回調函數中創建一個事件來標識超時數量的閥值 AutoResetEvent autoEvent = new AutoResetEvent(false); StatusChecker statusChecker = new StatusChecker(10); //為timer創建一個計時器的推斷委托 TimerCallback tcb = statusChecker.CheckStatus; //創建一個標識委托在1秒之後,每隔1/4秒就調用一次CheckStatus來計時器 Console.WriteLine("{0} Creating timer.\n", DateTime.Now.ToString("h:mm:ss.fff")); Timer stateTimer = new Timer(tcb, autoEvent, 1000, 250); //當autoEvent被標識,改變周期為每1/2分鐘一次 autoEvent.WaitOne(5000, false); stateTimer.Change(0, 500); Console.WriteLine("\nChanging period.\n"); //當autoEvent第二次被標識時,釋放timer autoEvent.WaitOne(5000, false); stateTimer.Dispose(); Console.WriteLine("\nDestroying timer."); } } class StatusChecker { private int invokeCount; private int maxCount; public StatusChecker(int count) { invokeCount = 0; maxCount = count; } //這個方法會被Timer委托調用 public void CheckStatus(Object stateInfo) { AutoResetEvent autoEvent = (AutoResetEvent)stateInfo; Console.WriteLine("{0} Checking status {1,2}.", DateTime.Now.ToString("h:mm:ss.fff"), (++invokeCount).ToString()); if(invokeCount == maxCount) { //重置counter並且給主線程一個信號 invokeCount = 0; autoEvent.Set(); } } }
補充:
AutoResetEvent 允許線程通過發信號互相通信。通常,此通信涉及線程需要獨占訪問的資源。
線程通過調用 AutoResetEvent 上的 WaitOne 來等待信號。如果 AutoResetEvent 處於非終止狀態,則該線程阻塞,並等待當前控制資源的線程
通過調用 Set 發出資源可用的信號。
調用 Set 向 AutoResetEvent 發信號以釋放等待線程。AutoResetEvent 將保持終止狀態,直到一個正在等待的線程被釋放,然後自動返回非終止狀態。如果沒有任何線程在等待,則狀態將無限期地保持為終止狀態。
可以通過將一個布爾值傳遞給構造函數來控制 AutoResetEvent 的初始狀態,如果初始狀態為終止狀態,則為 true;否則為 false。
通俗的來講只有等myResetEven.Set()成功運行後,myResetEven.WaitOne()才能夠獲得運行機會;Set是發信號,WaitOne是等待信號,只有發了信號,
等待的才會執行。如果不發的話,WaitOne後面的程序就永遠不會執行
這段補充來自:http://www.cnblogs.com/lzjsky/archive/2011/07/11/2102794.html
System.Windows.Forms.Timer,貼code:
//在工具箱中拖了個timer過來.會生成下面的這部分code片段 #region 窗體設計部分的代碼可不用看 partial class Form1 { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.timer1 = new System.Windows.Forms.Timer(this.components); this.SuspendLayout(); // // timer1 // this.timer1.Tick += new System.EventHandler(this.timer1_Tick); // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(646, 455); this.Name = "Form1"; this.Text = "Form1"; this.Load += new System.EventHandler(this.Form1_Load); this.ResumeLayout(false); } #endregion private System.Windows.Forms.Timer timer1; } #endregion //要註意的是下面的這行事件綁定代碼: this.timer1.Tick += new System.EventHandler(this.timer1_Tick); //在初始化或Load事件,再或者在窗體中直接設置 timer1.Interval = 1000;//每秒執行一次 //下面就是你要執行的方法的主體部分 private void timer1_Tick(object sender, EventArgs e) { Console.WriteLine("我還會回來的!"); }
本文參考:
官方對Timer的解釋:https://msdn.Microsoft.com/en-us/library/system.threading.timer.aspx
感覺幫助的討論:http://stackoverflow.com/questions/1416803/system-timers-timer-vs-system-threading-timer
這位仁兄也有例子:http://www.cnblogs.com/Joetao/articles/2643378.html
Tags:
文章來源: