1. 程式人生 > >C#定時器

C#定時器

在C#裡關於定時器類有3個:
1.  定義在System.Windows.Forms裡
實現在使用者定義的時間間隔引發事件的計時器。此計時器最宜用於 Windows 窗體應用程式中,並且必須在視窗中使用。
名稱空間:System.Windows.Forms
程式集:System.Windows.Forms(在 system.windows.forms.dll 中)
備註:
Timer 用於以使用者定義的事件間隔觸發事件。Windows 計時器是為單執行緒環境設計的,其中,UI 執行緒用於執行處理。它要求使用者程式碼有一個可用的 UI 訊息泵,而且總是在同一個執行緒中操作,或者將呼叫封送到另一個執行緒。
使用此計時器時,請使用控制元件的Tick事件執行輪詢操作,或在指定的時間內顯示啟動畫面。每當 Enabled 屬性設定為true且Interval屬性大於0時,將引發Tick事件,引發的時間間隔基於Interval屬性設定。

此類提供用於設定時間間隔以及啟動和停止計時器的方法。
注意:Windows窗體Timer元件是單執行緒元件,精度限定為55毫秒。如果您需要更高精度的多執行緒計時器,請使用System.Timers名稱空間中的Timer類。
執行緒安全:
此型別的任何公共靜態(Visual Basic中的Shared)成員都是執行緒安全的,但不保證所有例項成員都是執行緒安全的。
例子:
public class Class1 {
    static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
    static int alarmCounter = 1;
    static bool exitFlag = false;
    // This is the method to run when the timer is raised.
    private static void TimerEventProcessor(Object myObject,
                                            EventArgs myEventArgs) {
       myTimer.Stop();

       // Displays a message box asking whether to continue running the timer.
       if(MessageBox.Show("Continue running?", "Count is: " + alarmCounter,
          MessageBoxButtons.YesNo) == DialogResult.Yes) {
          // Restarts the timer and increments the counter.
          alarmCounter +=1;
          myTimer.Enabled = true;
       }
       else {
          // Stops the timer.
          exitFlag = true;
       }
    }
    public static int Main() {
       myTimer.Tick += new EventHandler(TimerEventProcessor);
       // Sets the timer interval to 5 seconds.
       myTimer.Interval = 5000;
       myTimer.Start();

       // Runs the timer, and raises the event.
       while(exitFlag == false) {
          // Processes all the events in the queue.
          Application.DoEvents();
       }
    return 0;
    }
 }

平臺:
Windows 98、Windows 2000 SP4、Windows CE、Windows Millennium Edition、Windows Mobile for Pocket PC、Windows Mobile for Smartphone、Windows Server 2003、Windows XP Media Center Edition、Windows XP Professional x64 Edition、Windows XP SP2、Windows XP Starter Edition
.NET Framework並不是對每個平臺的所有版本都提供支援。有關受支援版本的列表,請參見系統要求。
版本資訊:
.NET Framework
受以下版本支援:2.0、1.1、1.0
.NET Compact Framework
受以下版本支援:2.0、1.0
         2.  定義在System.Timers.Timer類裡
在應用程式中生成定期事件。
名稱空間:System.Timers
程式集:System(在 system.dll 中)
備註:
注意:應用於此類的HostProtectionAttribute屬性(Attribute)具有以下Resources屬性 (Property)值:Synchronization | ExternalThreading。HostProtectionAttribute不影響桌面應用程式(這些應用程式通常通過雙擊圖示、鍵入命令或在瀏覽器中輸入 URL 來啟動)。有關更多資訊,請參見HostProtectionAttribute類或SQL Server程式設計和宿主保護屬性。
Timer元件是基於伺服器的計時器,它使您能夠指定在應用程式中引發 Elapsed 事件的週期性間隔。然後可以操控此事件以提供定期處理。例如,假設您有一臺關鍵性伺服器,必須每週7天、每天24小時都保持執行。可以建立一個使用 Timer的服務,以定期檢查伺服器並確保系統開啟並在執行。如果系統不響應,則該服務可以嘗試重新啟動伺服器或通知管理員。
       基於伺服器的Timer是為在多執行緒環境中用於輔助執行緒而設計的。伺服器計時器可以線上程間移動來處理引發的Elapsed事件,這樣就可以比Windows計時器更精確地按時引發事件。有關基於伺服器的計時器的更多資訊,請參見"基於伺服器的計時器介紹"。
        基於Interval屬性的值,Timer元件引發Elapsed事件。可以處理該事件以執行所需的處理。例如,假設您有一個聯機銷售應用程式,它不斷向資料庫傳送銷售訂單。編譯發貨指令的服務分批處理訂單,而不是分別處理每個訂單。可以使用Timer每30分鐘啟動一次批處理。
        注意:當AutoReset設定為false時,Timer只在第一個Interval過後引發一次Elapsed事件。若要保持以Interval時間間隔引發Elapsed事件,請將AutoReset設定為true。
        Elapsed 事件在ThreadPool執行緒上引發。如果Elapsed事件的處理時間比Interval長,在另一個ThreadPool執行緒上將會再次引發此事件。因此,事件處理程式應當是可重入的。
        注意:在一個執行緒呼叫Stop方法或將Enabled屬性設定為false的同時,可在另一個執行緒上執行事件處理方法。這可能導致在計時器停止之後引發Elapsed事件。Stop方法的示例程式碼演示了一種避免此爭用條件的方法。
如果和使用者介面元素(如窗體或控制元件)一起使用Timer,請將包含有Timer的窗體或控制元件賦值給SynchronizingObject屬性,以便將此事件封送到使用者介面執行緒中。
Timer在執行時是不可見的。
有關Timer的例項的初始屬性值列表,請參見Timer建構函式。
執行緒安全:
此型別的任何公有static成員對多執行緒操作都是安全的。但不能保證任何例項成員是執行緒安全的。
例子:
使用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!");   
 }
平臺:
Windows 98、Windows 2000 SP4、Windows Millennium Edition、Windows Server 2003、Windows XP Media Center Edition、Windows XP Professional x64 Edition、Windows XP SP2、Windows XP Starter Edition
.NET Framework 並不是對每個平臺的所有版本都提供支援。有關受支援版本的列表,請參見系統要求。
版本資訊:
.NET Framework
受以下版本支援:2.0、1.1、1.0
       3.  定義在System.Threading.Timer類裡
提供以指定的時間間隔執行方法的機制。無法繼承此類。
名稱空間:System.Threading
程式集:mscorlib(在 mscorlib.dll 中)
備註:
注意:應用於此類的HostProtectionAttribute屬性(Attribute)具有以下Resources屬性 (Property)值:Synchronization | ExternalThreading。HostProtectionAttribute並不會影響桌面應用程式(桌面應用程式通常通過雙擊圖示、鍵入命令或在瀏覽器中輸入 URL 來啟動)。有關更多資訊,請參見HostProtectionAttribute類或SQL Server程式設計和宿主保護屬性。

使用TimerCallback委託指定希望Timer執行的方法。計時器委託在構造計時器時指定,並且不能更改。此方法不在建立計時器的執行緒上執行,而是在系統提供的ThreadPool執行緒上執行。
建立計時器時,可以指定在第一次執行方法之前等待的時間量(截止時間)以及此後的執行期間等待的時間量(時間週期)。可以使用Change方法更改這些值或禁用計時器。
        注意:只要在使用Timer,就必須保留對它的引用。對於任何託管物件,如果沒有對Timer的引用,計時器會被垃圾回收。即使Timer仍處在活動狀態,也會被回收。(我在這裡就出現了錯誤,計時器活動狀態下卻不運行了)當不再需要計時器時,請使用Dispose方法釋放計時器持有的資源。如果希望在計時器被釋放時接收到訊號,請使用接受WaitHandle的Dispose(WaitHandle)方法過載。計時器已被釋放後,WaitHandle便終止。
        由計時器執行的回撥方法應該是可重入的,因為它是在ThreadPool執行緒上呼叫的。在以下兩種情況中,此回撥可以同時在兩個執行緒池執行緒上執行:一是計時器間隔小於執行此回撥所需的時間;二是所有執行緒池執行緒都在使用,此回撥被多次排隊。
注意:System.Threading.Timer是一個使用回撥方法的計時器,而且由執行緒池執行緒服務,簡單且對資源要求不高。也可以考慮與 Windows窗體一起使用的System.Windows.Forms.Timer基於伺服器計時器功能的System.Timers.Timer。這些計時器使用事件並具有附加功能。

執行緒安全:
該型別對於多執行緒操作是安全的。
using System;
using System.Threading;

class TimerExample
{
    static void Main()
    {
        AutoResetEvent autoEvent     = new AutoResetEvent(false);
        StatusChecker  statusChecker = new StatusChecker(10);

        // Create the delegate that invokes methods for the timer.
        TimerCallback timerDelegate =
            new TimerCallback(statusChecker.CheckStatus);

        // Create a timer that signals the delegate to invoke
        // CheckStatus after one second, and every 1/4 second
        // thereafter.
        Console.WriteLine("{0} Creating timer.\n",
            DateTime.Now.ToString("h:mm:ss.fff"));
        Timer stateTimer =
                new Timer(timerDelegate, autoEvent, 1000, 250);

        // When autoEvent signals, change the period to every
        // 1/2 second.
        autoEvent.WaitOne(5000, false);
        stateTimer.Change(0, 500);
        Console.WriteLine("\nChanging period.\n");

        // When autoEvent signals the second time, dispose of
        // the timer.
        autoEvent.WaitOne(5000, false);
        stateTimer.Dispose();
        Console.WriteLine("\nDestroying timer.");
    }
}

class StatusChecker
{
    int invokeCount, maxCount;

    public StatusChecker(int count)
    {
        invokeCount  = 0;
        maxCount = count;
    }

    // This method is called by the timer delegate.
    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)
        {
            // Reset the counter and signal Main.
            invokeCount  = 0;
            autoEvent.Set();
        }
    }
}

版本資訊:
.NET Framework
受以下版本支援:2.0、1.1、1.0
.NET Compact Framework
受以下版本支援:2.0、1.0