天天看點

C#實作定時器的幾種方案

前幾天寫了一篇java的定時器方案,應小夥伴的要求,今天這裡一下c#實作定時器的方案。

在C#裡關于定時器類就有三個

1、System.Windows.Forms.Timer

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,完全取代上面的System.Windows.Forms.Timer控件。

System.Windows.Forms.Timer

計時器最宜用于 Windows 窗體應用程式中,并且必須在視窗中使用,适用于單線程環境,

在此環境中, UI 線程用于執行處理。 它要求使用者代碼提供 UI 消息泵, 并且始終從同一線程操作, 或将調用封送到

其他線程。Windows 窗體計時器元件是單線程的, 且限制為55毫秒的準确度,準确性不高

public partial class frmTimerDemo : Form
 {
 private System.Windows.Forms.Timer timerGetTime;

 private void frmTimerDemo_Load(object sender, EventArgs e)
 {
 //建立定時器
 timerGetTime = new System.Windows.Forms.Timer();
 //設定定時器屬性
 timerGetTime.Tick+=new EventHandler(HandleTime);
 timerGetTime.Interval = 1000;
 timerGetTime.Enabled = true;
 //開啟定時器
 timerGetTime.Start();
 }
 public void HandleTime(Object myObject, EventArgs myEventArgs)
 {
 labelTime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
 }
 private void frmTimerDemo_FormClosed(object sender, FormClosedEventArgs e)
 {
 //停止定時器
 timerGetTime.Stop();
 }
 }
           

System.Timers.Timer這個是目前我們定時項目中常用的。

System.Timers.Timer t = new System.Timers.Timer(10000);//執行個體化Timer類,設定間隔時間為10000毫秒;
t.Elapsed += new System.Timers.ElapsedEventHandler(Execute);//到達時間的時候執行事件;
t.AutoReset = true;//設定是執行一次(false)還是一直執行(true);
t.Enabled = true;//是否執行System.Timers.Timer.Elapsed事件;
t.Start(); //啟動定時器
//上面初始化代碼可以寫到構造函數中

 
public void Execute(object source, System.Timers.ElapsedEventArgs e)
{
 t.Stop(); //先關閉定時器
 MessageBox.Show("OK!");
t.Start(); //執行完畢後再開啟器
}
           

這裡需要注意的是Execute方法中一定要先關閉定時器,執行完畢後再開啟。這個是本人經過測試的,如果你注釋掉這兩句,定時器會不斷的執行Execute方法,如果Execute執行的是一個很耗時的方法,會導緻方法未執行完畢,定時器又啟動了一個線程來執行Execute方法。

System.Threading.Timer

線程計時器也不依賴窗體,是一種簡單的、輕量級計時器,它使用回調方法而不是使用事件,并由線程池線程提供支援,先看下面代碼

class Program
 {
 int TimesCalled = 0;
 void Display(object state)
 {
 Console.WriteLine("{0} {1} keep running.", (string)state, ++TimesCalled);
 }
 static void Main(string[] args)
 {
 Program p = new Program();
 //2秒後第一次調用,每1秒調用一次
 System.Threading.Timer myTimer = new System.Threading.Timer(p.Display, "Processing timer event", 2000, 1000);
 // 第一個參數是:回調方法,表示要定時執行的方法,第二個參數是:回調方法要使用的資訊的對象,或者為空引用,第三個參數是:調用 callback 之前延遲的時間量(以毫秒為機關),指定 Timeout.Infinite 以防止計時器開始計時。指定零 (0) 以立即啟動計時器。第四個參數是:定時的時間時隔,以毫秒為機關

 Console.WriteLine("Timer started.");
 Console.ReadLine();
 }
 }
           

上面是c#定時器的集中方案,大家在使用中一定要盡量把定時器聲明成靜态(static),如果放在執行個體方法中,會導緻執行個體對象被回收導緻定時器失效。

如果這篇文章對您有幫助,可轉發分享一下。