.NET Framework裡面提供了三種Timer
System.Windows.Forms.Timer
System.Timers.Timer
System.Threading.Timer
一、System.Windows.Forms.Timer
1、基於Windows消息循環,用事件方式觸發,在界面線程執行;是使用得比較多的Timer,Timer Start之後定時(按設定的Interval)調用掛接在Tick事件上的EvnetHandler。在這種Timer的EventHandler中可 以直接獲取和修改UI元素而不會出現問題--因為這種Timer實際上就是在UI線程自身上進行調用的。
2、它是一個基於Form的計時器
3、創建之後,你可以使用Interval設置Tick之間的跨度,用委托(delegate)hook Tick事件
4、調用Start和Stop方法,開始和停止
5、完全基於UI線程,因此部分UI相關的操作會在這個計時器內進行
6、長時間的UI操作可能導致部分Tick丟失
例如
C# 代碼 復制public partial class Form1 : Form
{ public Form1() { InitializeComponent(); } int num = 0; private void Form_Timer_Tick(object sender, EventArgs e) { label1.Text = (++num).ToString(); Thread.Sleep(3000); } private void button1_Click(object sender, EventArgs e) { Form_Timer.Start(); } private void button2_Click(object sender, EventArgs e) { Form_Timer.Stop(); } }
實例解析
1、上面這個是一個很簡單的功能,在Form窗體上拖了一個System.Windows.Forms.Timer控件名字為Form_Timer,在屬性窗中把Enable屬性設置為Ture,Interval是定時器的間隔時間。雙擊這個控件就可以看到 Form_Timer_Tick方法。在這個方法中,我們讓她不停的加一個數字並顯示在窗體上,2個按鈕提供了對計時器的控制功能。
2、執行的時候你去點擊其他窗體在回來,你會發現我們的窗體失去響應了。因為我們這裡使用Thread.Sleep(3000);讓當前線程掛起,而UI失去相應,說明了這裡執行時候采用的是單線程。也就是執行定時器的線程就是UI線程。
3、Timer 用於以用戶定義的事件間隔觸發事件。Windows 計時器是為單線程環境設計的,其中,UI 線程用於執行處理。它要求用戶代碼有一個可用的 UI 消息泵,而且總是在同一個線程中操作,或者將調用封送到另一個線程。
4、在Timer內部定義的了一個Tick事件,我們前面雙擊這個控件時實際是增加了一行代碼
this.Form_Timer.Tick += new System.EventHandler(this.Form_Timer_Tick);
然後Windows將這個定時器與調用線程關聯(UI線程)。當定時器觸發時,Windows把一個定時器消息插入到線程消息隊列中。調用線程執行一個消息泵提取消息,然後發送到回調方法中(這裡的Form_Timer_Tick方法)。而這些都是單線程進行了,所以在執行回調方法時UI會假死。所以使用這個控件不宜執行計算受限或IO受限的代碼,因為這樣容易導致界面假死,而應該使用多線程調用的Timer。另外要注意的是這個控件時間精度不高,精度限定為 55 毫秒。
二、System.Timers.Timer
1. 用的不是Tick事件,而是Elapsed事件
2. 和System.Windows.Forms.Timer一樣,用Start和Stop方法
3. AutoReset屬性決定計時器是不是要發起一次事件然後停止,還是進入開始/等待的循環。System.Windows.Forms.Timer沒有這個屬性
4. 設置對於UI控件的同步對象(synchronizing object),對控件的UI線程發起事件
例如
C# 代碼 復制public partial class Form1 : Form
{ public Form1() { InitializeComponent(); } int num = 0; DateTime time1 = new DateTime(); DateTime time2 = new DateTime(); //定義Timer System.Timers.Timer Timers_Timer = new System.Timers.Timer(); private void button1_Click(object sender, EventArgs e) { //手動設置Timer,開始執行 Timers_Timer.Interval = 20; Timers_Timer.Enabled = true; Timers_Timer.Elapsed += new System.Timers.ElapsedEventHandler(Timers_Timer_Elapsed); time1 = DateTime.Now; } void Timers_Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { label1.Text = Convert.ToString((++num)); //顯示到lable Thread.Sleep(3000); } private void button2_Click(object sender, EventArgs e) { //停止執行 Timers_Timer.Enabled = false; time2 = DateTime.Now; MessageBox.Show(Convert.ToString(time2-time1)); } }
三、System.Threading.Timer
C# 代碼 復制public partial class Form1 : Form
{ public Form1() { InitializeComponent(); } int num = 0; DateTime time1 = new DateTime(); DateTime time2 = new DateTime(); System.Threading.Timer Thread_Time; private void button1_Click(object sender, EventArgs e) { //啟動 Thread_Time = new System.Threading.Timer(Thread_Timer_Method,null,0,20); time1 = DateTime.Now; } void Thread_Timer_Method(object o) { label1.Text = Convert.ToString((++num)); System.Threading.Thread.Sleep(3000); } private void button2_Click(object sender, EventArgs e) { //停止 Thread_Time.Dispose(); time2 = DateTime.Now; MessageBox.Show(Convert.ToString(time2-time1)); } }
實例解析
1、用Threading.Timer時的方法,和前面就不太相同了,所以的參數全部在構造函數中進行了設置,而且可以設置啟動時間。而且沒有提供start和stop方法來控制計時器。而且是以一種回調方法的方式實現,而不是通過事件來實現的。他們之間還是有區別的。
2、我們只有銷毀掉對象來停止他。當你運行時,你會發現他和前面的Timers.Timer一樣,是多線程的,主要表現在不會假死,調試運行報錯。但跟讓你奇怪的是,我們的代碼竟然無法讓她停止下來。調用了Dispose方法沒有用。問題在那?然後有進行了測試,修改了間隔時間為100,200,500,1000,3000,4000。這幾種情況。發現當間隔為500ms以上是基本馬上就停止了。而間隔時間相對執行時間越短,繼續執行的時間越長。這應該是在間隔時間小於執行時間時多個線程運行造成的。因為所有的線程不是同時停止的。間隔越短,線程越多,所以執行次數越多。
3、System.Threading.Timer 是一個簡單的輕量計時器,它使用回調方法並由線程池線程提供服務。不建議將其用於 Windows 窗體,因為其回調不在用戶界面線程上進行。
在C#裡關於定時器類就有3個
1.定義在System.Windows.Forms裡
2.定義在System.Threading.Timer類裡
3.定義在System.Timers.Timer類裡
System.Windows.Forms.Timer是應用於WinForm中的,它是通過Windows消息機制實現的,類似於VB或Delphi中的Timer控件,內部使用API SetTimer實現的。它的主要缺點是計時不精確,而且必須有消息循環,Console Application(控制台應用程序)無法使用。
System.Timers.Timer和System.Threading.Timer非常類似,它們是通過.NET Thread Pool實現的,輕量,計時精確,對應用程序、消息沒有特別的要求。System.Timers.Timer還可以應用於WinForm,完全取代上面的Timer控件。它們的缺點是不支持直接的拖放,需要手工編碼。
例:
使用System.Timers.Timer類
System.Timers.Timer t = new System.Timers.Timer(10000);//實例化Timer類,設置間隔時間為10000毫秒;
t.Elapsed += new System.Timers.ElapsedEventHandler(theout);//到達時間的時候執行事件;
t.AutoReset = true;//設置是執行一次(false)還是一直執行(true);
t.Enabled = true;//是否執行System.Timers.Timer.Elapsed事件;
public void theout(object source, System.Timers.ElapsedEventArgs e)
{
MessageBox.Show("OK!");
}
System.Windows.forms.Timer這個是winform自帶控件 要使用它只能在winform中System.Threading.Timer 這個是線程timer 主要用於多個線程之間互相鏈接用System.Timers.Timer; 這個是主要用戶winform其他類 因為timer在窗體類中 如果要在其他類調用時間線程 就用這個