c# 中定時器的用法


來源於:http://blog.sina.com.cn/s/blog_62c501440100fog1.html

 

System.Threading.Timer 是一個非常常用的定時器類,關於這個類的使用,我們需要注意以下幾點:
   1.System.Threading.Timer 的任何一個實例,實際上是通過使用win32底層(非.NET Thread Pool中的線程)來進行調度的。
   2.當到達調度時刻時,System.Threading.Timer 將異步調用由TimerCallback參數指定的回調方法。也就是說TimerCallback所指向的方法將在.NET Thread Pool中的工作者線程中執行。
   3.當.NET Thread Pool中沒有空閑線程時,對TimerCallback所指向的方法的調用將被ThreadPool排隊。而這並不會影響System.Threading.Timer的正常調度過程--當到達調度時間點,System.Threading.Timer仍然觸發異步調用。
   順便補充一下,經過我的測試發現,ThreadPool中默認的最大工作線程數是25/CPU,最大完成端口線程數是1000。(雙核最大工作線程就是25*2/CPU)
 

 

System.Threading.Timer 是一個使用回調方法的計時器,而且由線程池線程服務,簡單且對資源要求不高。
只要在使用 Timer,就必須保留對它的引用。對於任何托管對象,如果沒有對 Timer 的引用,計時器會被垃圾回收。即使 Timer 仍處在活動狀態,也會被回收。當不再需要計時器時,請使用 Dispose 方法釋放計時器持有的資源。
 
使用 TimerCallback 委托指定希望 Timer 執行的方法。計時器委托在構造計時器時指定,並且不能更改。此方法不在創建計時器的線程中執行,而是在系統提供的線程池線程中執行。
 
創建計時器時,可以指定在第一次執行方法之前等待的時間量(截止時間)以及此后的執行期間等待的時間量(時間周期)。可以使用 Change 方法更改這些值或禁用計時器。

 

 

Demo application:
應用場景:在windows form程序自動執行某項工作后,希望其windows form能夠自動關閉。
代碼設計:(1)首先聲明Timer變量:
private System.Threading.Timer timerClose;
 
(2)在上述自動執行代碼后面添加如下Timer實例化代碼:
// Create a timer thread and start it
timerClose = new System.Threading.Timer(new TimerCallback(timerCall), this, 5000, 0);
 
Timer構造函數參數說明:
Callback:一個 TimerCallback 委托,表示要執行的方法。
State:一個包含回調方法要使用的信息的對象,或者為空引用(Visual Basic 中為 Nothing)。
dueTime:調用 callback 之前延遲的時間量(以毫秒為單位)。指定 Timeout.Infinite 以防止計時器開始計時。指定零 (0) 以立即啟動計時器。
Period:調用 callback 的時間間隔(以毫秒為單位)。指定 Timeout.Infinite 可以禁用定期終止。
 
(3)定義TimerCallback委托要執行的方法:
private void timerCall(object obj)
{
      timerClose.Dispose();
      this.Close();
}
 
當然,除了使用上述System.Threading.Timer類的TimerCallback 委托機制外,應該還有很多其他的辦法。另外,這里只是demo了TimerCallback委托的簡單應用。
-------------------------------------------------------------------------------------------------------------------------------------------------------
轉載地址:http://www.jb51.net/article/56725.htm

本文實例講述了C#中Forms.Timer、Timers.Timer、Threading.Timer的用法分析,分享給大家供大家參考。具體分析如下:

在.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丟失

例如

 

復制代碼代碼如下:
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線程發起事件

例如

 

復制代碼代碼如下:
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

 

復制代碼代碼如下:
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#程序設計有所幫助。


免責聲明!

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



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