C#.NET定時器類及使用方法
C#.NET 定時器類及使用方法
在.net常用的定時器類有下面三種,使用定時器時需要設定引數,如間斷時間、定時器計溢位後的回撥函式、延時、開始等,定時器的的主要方法有開始、終止等,不同的定時器實現上述的方法會有一些差異,本文會針對具體的定時器一一舉例說明。
- 1、System.Windows.Forms.Timer類
- 2、System.Threading.Timer類
- 3、System.Timers.Timer類
一、System.Windows.Forms.Timer
從這個定時器的名稱空間可以看出,.net設計這個定時器的目的是為了方便程式設計師在Window Form中使用的定時器。當一個System.Windows.Forms.Timer類被構造時,當前定時器會和當前執行緒進行關聯。而當計時器的計滿後,一個定時器訊息將被插入到當前執行緒的訊息佇列中。當前執行緒逐一處理訊息中的所有訊息,並一一派發給各自的處理方法。這樣的機制和利用工作者程序定時有很大的區別,System.Windows.Forms.Timer型別並沒有涉及多執行緒的操作,定時器的設定、定時方法的執行都在同一個執行緒之上。這就意味著System.Windows.Forms.Timer並不能準確計時,尤其當訊息阻塞時,定時器的誤差將會更大,因為定時器訊息只能等待在前面的所有訊息處理完後才能得到處理。但是因為System.Windows.Forms.Timer型別的定時器並不涉及多執行緒的操作,因此是執行緒安全的,不會發生回撥方法重入的問題。
主要使用步驟如下:
1. System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();//例項化
2. myTimer.Tick += new EventHandler(函式名); //給timer掛起事件
3. myTimer.Enabled = true;//使timer可用
4. myTimer.Interval = n; //設定時間間隔,以毫秒為單位
5. myTimer.Stop(); //如果要暫停計時則使用Stop()方法
6. myTimer.Enabled = false;//若要停止使用timer,則使之不可用
System.Windows.Forms.Timer例程:
[csharp]
- using System.Windows.Forms;
- namespace WindowsFormsApplication1
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- }
- //例項化一個timer
- System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
- private void StartTimeBtn_Click(object sender, EventArgs e)//開始計時
- {
- //給timer掛起事件
- myTimer.Tick += new EventHandler(Callback);
- //使timer可用
- myTimer.Enabled = true;
- //設定時間間隔,以毫秒為單位
- myTimer.Interval = 1000;//1s
- }
- private void StopTimeBtn_Click(object sender, EventArgs e)//停止計時
- {
- //計時開始
- myTimer.Stop();
- }
- //回撥函式
- private void Callback(object sender, EventArgs e)
- {
- //獲取系統時間 20:16:16
- textBox1.Text = DateTime.Now.ToLongTimeString().ToString();
- }
- }
- }
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//例項化一個timer
System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
private void StartTimeBtn_Click(object sender, EventArgs e)//開始計時
{
//給timer掛起事件
myTimer.Tick += new EventHandler(Callback);
//使timer可用
myTimer.Enabled = true;
//設定時間間隔,以毫秒為單位
myTimer.Interval = 1000;//1s
}
private void StopTimeBtn_Click(object sender, EventArgs e)//停止計時
{
//計時開始
myTimer.Stop();
}
//回撥函式
private void Callback(object sender, EventArgs e)
{
//獲取系統時間 20:16:16
textBox1.Text = DateTime.Now.ToLongTimeString().ToString();
}
}
}
二、System.Threading.Timer
這個定時器類的使用相對複雜,但同時它也是最優化的一個定時器型別。System.Threading.Timer的定時方法在獨立的執行緒上執行,定時時間更為準確。所有的物件有一個執行緒控制,當下一個定時到達時,該執行緒會負責線上程中獲得一個新的工作者執行緒,用以執行相應的回撥方法。雖然這個定時器是相對最優化的一個定時器型別,但是從其機制上來講,其並不是執行緒安全的,可能會出現回撥方法重入的問題。解釋下方法重入,是一個有關多執行緒程式設計的概念,意思大概是:同一程式中,多個執行緒同時執行時,就可能發生同一個方法被多個程序同時呼叫的情況。當這個方法中存在一些非執行緒安全的程式碼時,方法重入會導致資料發生同步錯誤的bug。
主要使用步驟如下:
1、例項構造一個執行緒定時器。
System.Threading.Timer mytimer =
new System.Threading.Timer(new System.Threading.TimerCallback(timerCall), null, 0, 1000);
★timer建構函式資料:
[csharp] view plain copy print ?
- public Timer(
- TimerCallback callback, // TimerCallback 委託,表示要執行的方法。
- object state, //一個包含回撥方法要使用的資訊的物件,或者為 null。
- int dueTime, //呼叫 callback 之前延遲的時間量(以毫秒為單位)。
- //指定 Timeout.Infinite 可防止啟動計時器。
- // 指定零 (0) 可立即啟動計時器。
- //指定零 (-1) 表示本定時器被禁用。
- //Change(Int32,Int32)方法可以改寫定時器引數
- int period //如果 period 為零 (0) 或 -1 毫秒,而且dueTime 為正
- //則只會呼叫一次 callback;
- //然後計時器的定時行為將被禁用,使用 Change 可以改寫定時器引數。
- )
public Timer( TimerCallback callback, // TimerCallback 委託,表示要執行的方法。 object state, //一個包含回撥方法要使用的資訊的物件,或者為 null。 int dueTime, //呼叫 callback 之前延遲的時間量(以毫秒為單位)。 //指定 Timeout.Infinite 可防止啟動計時器。 // 指定零 (0) 可立即啟動計時器。 //指定零 (-1) 表示本定時器被禁用。 //Change(Int32,Int32)方法可以改寫定時器引數 int period //如果 period 為零 (0) 或 -1 毫秒,而且dueTime 為正 //則只會呼叫一次 callback; //然後計時器的定時行為將被禁用,使用 Change 可以改寫定時器引數。 )
https://msdn.microsoft.com/zh-cn/library/system.threading.timer(v=vs.110).aspx
2、編寫timerCall回撥函式
格式:private void timerCall(object xxxxx) { …….; …….;}
3、使用Change(Int32,Int32)方法來修改定時器引數實現停止、重新開始等。
4、使用Dispose()方法釋放定時器資源。
System.Threading.Timer例程:
[csharp] view plain copy
- public startTimer()
- {
- //定義一個物件
- System.Threading.Timer timer = new System.Threading.Timer(
- new System.Threading.TimerCallback(mytimer), null,
- 0, 1000);//1S定時器
- }
- //函式形式引數必須是object格式
- public void mytimer(object a )
- {
- Console.WriteLine(”你好”);
- }
public startTimer()
{
//定義一個物件
System.Threading.Timer timer = new System.Threading.Timer(
new System.Threading.TimerCallback(mytimer), null,
0, 1000);//1S定時器
}
//函式形式引數必須是object格式
public void mytimer(object a )
{
Console.WriteLine("你好");
}</pre>
三、 System.Timers.Timer類
這是一個相對較舊的型別,它和System.Threading.Timer一樣,可以由工作者執行緒來執行回撥方法,但同時它也可以在IDE環境中被拖到窗體控制元件上,這個時候它的行為非常類似於System.Windows.Forms.Timer型別,在訊息過多時其定時並不準確。 System.Timers.Timer可以視為System.Threading.Timer的一個包裝,其型別設計相對古老,不建議使用該定時器。
System.Timers.Timer例程程式碼:
[csharp] view plain copy
- System.Timers.Timer t = newSystem.Timers.Timer(5000); //設定時間間隔為5秒
- private void Form1_Load(object sender,EventArgs e)
- {
- t.Elapsed += newSystem.Timers.ElapsedEventHandler(Timer_TimesUp);
- t.AutoReset = false; //每到指定時間Elapsed事件是觸發一次(false),還是一直觸發(true)
- }
- private void btnStart_Click(objectsender, EventArgs e)
- {
- t.Enabled = true; //是否觸發Elapsed事件
- t.Start();
- }
- private void Timer_TimesUp(objectsender, System.Timers.ElapsedEventArgs e)
- {
- //到達指定時間5秒觸發該事件輸出 HelloWorld!!!!
- System.Diagnostics.Debug.WriteLine(”HelloWorld!!!!”);
- }
- private void btnStop_Click(objectsender, EventArgs e)
- {
- t.Stop();
- System.Diagnostics.Debug.WriteLine(”未到指定時間5秒提前終結!!!”);
- }
System.Timers.Timer t = newSystem.Timers.Timer(5000); //設定時間間隔為5秒
private void Form1_Load(object sender,EventArgs e)
{
t.Elapsed += newSystem.Timers.ElapsedEventHandler(Timer_TimesUp);
t.AutoReset = false; //每到指定時間Elapsed事件是觸發一次(false),還是一直觸發(true)
}
private void btnStart_Click(objectsender, EventArgs e)
{
t.Enabled = true; //是否觸發Elapsed事件
t.Start();
}
private void Timer_TimesUp(objectsender, System.Timers.ElapsedEventArgs e)
{
//到達指定時間5秒觸發該事件輸出 HelloWorld!!!!
System.Diagnostics.Debug.WriteLine("HelloWorld!!!!");
}
private void btnStop_Click(objectsender, EventArgs e)
{
t.Stop();
System.Diagnostics.Debug.WriteLine("未到指定時間5秒提前終結!!!");
}</pre>
四、 System.Windows.Threading.DispatcherTimer型別(補充)
System.Windows.Threading.DispatcherTimer整合到按指定時間間隔和指定優先順序處理的 Dispatcher 佇列中的計時器。因為 DispatcherTimer 操作與其他操作一樣被放置到Dispatcher佇列中,何時執行DispatcherTimer 操作取決於佇列中的其他作業及其優先順序,因此它不能保證會正好在時間間隔發生時執行計時器,但能夠保證不會在時間間隔發生之前執行計時器。如果 System.Timers.Timer 用於 WPF 應用程式,則值得注意的是 System.Timers.Timer 運行於不同於user interface(UI) 執行緒的其他執行緒上。 為了訪問user interface (UI) 執行緒上的物件,需要使用 Invoke 或 BeginInvoke 將操作釋出到user interface (UI) 執行緒的 Dispatcher 上。
參考部落格連結:
http://www.cnblogs.com/DebugLZQ/archive/2012/08/05/2623669.html
http://blog.csdn.net/luols/article/details/5880232
http://www.360doc.com/content/11/0812/11/1039473_139824496.shtml
--------------------- 本文來自 在路上的工程師 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/qq_40691189/article/details/80196492?utm_source=copy