Timer 類別

定義

提供一套機制,可於指定間隔在執行緒集區執行緒上執行方法。 此類別無法獲得繼承。

public ref class Timer sealed : IDisposable
public ref class Timer sealed : MarshalByRefObject, IAsyncDisposable, IDisposable
public ref class Timer sealed : MarshalByRefObject, System::Threading::ITimer
public ref class Timer sealed : MarshalByRefObject, IDisposable
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class Timer : IDisposable
public sealed class Timer : MarshalByRefObject, IAsyncDisposable, IDisposable
public sealed class Timer : MarshalByRefObject, System.Threading.ITimer
public sealed class Timer : MarshalByRefObject, IDisposable
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class Timer : MarshalByRefObject, IDisposable
[<System.Runtime.InteropServices.ComVisible(true)>]
type Timer = class
    interface IDisposable
type Timer = class
    inherit MarshalByRefObject
    interface IAsyncDisposable
    interface IDisposable
type Timer = class
    inherit MarshalByRefObject
    interface IAsyncDisposable
    interface IDisposable
    interface ITimer
type Timer = class
    inherit MarshalByRefObject
    interface IDisposable
[<System.Runtime.InteropServices.ComVisible(true)>]
type Timer = class
    inherit MarshalByRefObject
    interface IDisposable
Public NotInheritable Class Timer
Implements IDisposable
Public NotInheritable Class Timer
Inherits MarshalByRefObject
Implements IAsyncDisposable, IDisposable
Public NotInheritable Class Timer
Inherits MarshalByRefObject
Implements ITimer
Public NotInheritable Class Timer
Inherits MarshalByRefObject
Implements IDisposable
繼承
Timer
繼承
屬性
實作

範例

下列範例會定義類別 StatusChecker ,其中包含 CheckStatus 簽章與委派相同的 TimerCallback 方法。 方法 stateCheckStatus 自變數是物件 AutoResetEvent ,用來同步處理應用程式線程和執行回呼委派的線程集區線程。 類別 StatusChecker 也包含兩個狀態變數:

invokeCount 指出已叫用回呼方法的次數。

maxCount 決定應該叫用回呼方法的最大次數。

應用程式線程會建立定時器,它會等候一秒,然後每隔 250 毫秒執行 CheckStatus 回呼方法。 應用程式線程接著會封鎖, AutoResetEvent 直到物件收到訊號為止。 CheckStatus回呼方法執行maxCount時間時,它會呼叫 方法,AutoResetEvent.Set將物件的狀態AutoResetEvent設定為已發出訊號。 第一次發生這種情況時,應用程式線程會呼叫 Change(Int32, Int32) 方法,讓回呼方法現在每隔半秒執行一次。 它會再次封鎖, AutoResetEvent 直到物件收到訊號為止。 發生這種情況時,定時器會藉由呼叫其 Dispose 方法終結,而應用程式會終止。

using namespace System;
using namespace System::Threading;

ref class StatusChecker
{
private:
    int invokeCount, maxCount;

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

    // This method is called by the timer delegate.
    void CheckStatus(Object^ stateInfo)
    {
        AutoResetEvent^ autoEvent = dynamic_cast<AutoResetEvent^>(stateInfo);
        Console::WriteLine("{0:h:mm:ss.fff} Checking status {1,2}.",
                           DateTime::Now, ++invokeCount);

        if (invokeCount == maxCount) {
            // Reset the counter and signal the waiting thread.
            invokeCount  = 0;
            autoEvent->Set();
        }
    }
};

ref class TimerExample
{
public:
    static void Main()
    {
        // Create an AutoResetEvent to signal the timeout threshold in the
        // timer callback has been reached.
        AutoResetEvent^ autoEvent = gcnew AutoResetEvent(false);

        StatusChecker^ statusChecker = gcnew StatusChecker(10);

        // Create a delegate that invokes methods for the timer.
        TimerCallback^ tcb =
           gcnew TimerCallback(statusChecker, &StatusChecker::CheckStatus);

        // Create a timer that invokes CheckStatus after one second, 
        // and every 1/4 second thereafter.
        Console::WriteLine("{0:h:mm:ss.fff} Creating timer.\n",
                           DateTime::Now);
        Timer^ stateTimer = gcnew Timer(tcb, autoEvent, 1000, 250);

        // When autoEvent signals, change the period to every half second.
        autoEvent->WaitOne(5000, false);
        stateTimer->Change(0, 500);
        Console::WriteLine("\nChanging period to .5 seconds.\n");

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

int main()
{
    TimerExample::Main();
}
// The example displays output like the following:
//       11:59:54.202 Creating timer.
//       
//       11:59:55.217 Checking status  1.
//       11:59:55.466 Checking status  2.
//       11:59:55.716 Checking status  3.
//       11:59:55.968 Checking status  4.
//       11:59:56.218 Checking status  5.
//       11:59:56.470 Checking status  6.
//       11:59:56.722 Checking status  7.
//       11:59:56.972 Checking status  8.
//       11:59:57.223 Checking status  9.
//       11:59:57.473 Checking status 10.
//       
//       Changing period to .5 seconds.
//       
//       11:59:57.474 Checking status  1.
//       11:59:57.976 Checking status  2.
//       11:59:58.476 Checking status  3.
//       11:59:58.977 Checking status  4.
//       11:59:59.477 Checking status  5.
//       11:59:59.977 Checking status  6.
//       12:00:00.478 Checking status  7.
//       12:00:00.980 Checking status  8.
//       12:00:01.481 Checking status  9.
//       12:00:01.981 Checking status 10.
//       
//       Destroying timer.
using System;
using System.Threading;

class TimerExample
{
    static void Main()
    {
        // Create an AutoResetEvent to signal the timeout threshold in the
        // timer callback has been reached.
        var autoEvent = new AutoResetEvent(false);
        
        var statusChecker = new StatusChecker(10);

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

        // When autoEvent signals, change the period to every half second.
        autoEvent.WaitOne();
        stateTimer.Change(0, 500);
        Console.WriteLine("\nChanging period to .5 seconds.\n");

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

class StatusChecker
{
    private int invokeCount;
    private int  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 the waiting thread.
            invokeCount = 0;
            autoEvent.Set();
        }
    }
}
// The example displays output like the following:
//       11:59:54.202 Creating timer.
//       
//       11:59:55.217 Checking status  1.
//       11:59:55.466 Checking status  2.
//       11:59:55.716 Checking status  3.
//       11:59:55.968 Checking status  4.
//       11:59:56.218 Checking status  5.
//       11:59:56.470 Checking status  6.
//       11:59:56.722 Checking status  7.
//       11:59:56.972 Checking status  8.
//       11:59:57.223 Checking status  9.
//       11:59:57.473 Checking status 10.
//       
//       Changing period to .5 seconds.
//       
//       11:59:57.474 Checking status  1.
//       11:59:57.976 Checking status  2.
//       11:59:58.476 Checking status  3.
//       11:59:58.977 Checking status  4.
//       11:59:59.477 Checking status  5.
//       11:59:59.977 Checking status  6.
//       12:00:00.478 Checking status  7.
//       12:00:00.980 Checking status  8.
//       12:00:01.481 Checking status  9.
//       12:00:01.981 Checking status 10.
//       
//       Destroying timer.
Imports System.Threading

Public Module Example
    Public Sub Main()
        ' Use an AutoResetEvent to signal the timeout threshold in the
        ' timer callback has been reached.
        Dim autoEvent As New AutoResetEvent(False)

        Dim statusChecker As New StatusChecker(10)

        ' Create a timer that invokes CheckStatus after one second, 
        ' and every 1/4 second thereafter.
        Console.WriteLine("{0:h:mm:ss.fff} Creating timer." & vbCrLf, 
                          DateTime.Now)
        Dim stateTimer As New Timer(AddressOf statusChecker.CheckStatus, 
                                    autoEvent, 1000, 250)

        ' When autoEvent signals, change the period to every half second.
        autoEvent.WaitOne()
        stateTimer.Change(0, 500)
        Console.WriteLine(vbCrLf & "Changing period to .5 seconds." & vbCrLf)

        ' When autoEvent signals the second time, dispose of the timer.
        autoEvent.WaitOne()
        stateTimer.Dispose()
        Console.WriteLine(vbCrLf & "Destroying timer.")
    End Sub
End Module

Public Class StatusChecker
    Dim invokeCount, maxCount As Integer 

    Sub New(count As Integer)
        invokeCount  = 0
        maxCount = count
    End Sub

    ' The timer callback method.
    Sub CheckStatus(stateInfo As Object)
        Dim autoEvent As AutoResetEvent = DirectCast(stateInfo, AutoResetEvent)
        invokeCount += 1
        Console.WriteLine("{0:h:mm:ss.fff} Checking status {1,2}.", 
                          DateTime.Now, invokeCount)
        If invokeCount = maxCount Then
            ' Reset the counter and signal the waiting thread.
            invokeCount = 0
            autoEvent.Set()
        End If
    End Sub
End Class
' The example displays output like the following:
'       11:59:54.202 Creating timer.
'       
'       11:59:55.217 Checking status  1.
'       11:59:55.466 Checking status  2.
'       11:59:55.716 Checking status  3.
'       11:59:55.968 Checking status  4.
'       11:59:56.218 Checking status  5.
'       11:59:56.470 Checking status  6.
'       11:59:56.722 Checking status  7.
'       11:59:56.972 Checking status  8.
'       11:59:57.223 Checking status  9.
'       11:59:57.473 Checking status 10.
'       
'       Changing period to .5 seconds.
'       
'       11:59:57.474 Checking status  1.
'       11:59:57.976 Checking status  2.
'       11:59:58.476 Checking status  3.
'       11:59:58.977 Checking status  4.
'       11:59:59.477 Checking status  5.
'       11:59:59.977 Checking status  6.
'       12:00:00.478 Checking status  7.
'       12:00:00.980 Checking status  8.
'       12:00:01.481 Checking status  9.
'       12:00:01.981 Checking status 10.
'       
'       Destroying timer.

備註

TimerCallback使用委派來指定您想要Timer執行的方法。 委派的 TimerCallback 簽章為:

void TimerCallback(Object state)
void TimerCallback(Object state)
Sub TimerCallback(state As Object)

定時器委派是在建構定時器時指定,而且無法變更。 方法不會在建立定時器的線程上執行;它會在系統提供的線程上 ThreadPool 執行。

提示

.NET 包含數個定時器類別,每個類別都提供不同的功能:

  • System.Timers.Timer,它會定期引發事件,並在一或多個事件接收中執行程序代碼。 類別適用於在多線程環境中做為伺服器型或服務元件;它沒有使用者介面,而且在運行時間看不到。
  • System.Threading.Timer,它會定期在線程集區線程上執行單一回呼方法。 當定時器具現化且無法變更時,就會定義回呼方法。 和類別 System.Timers.Timer 一樣,這個類別適用於在多線程環境中做為伺服器型或服務元件;它沒有使用者介面,而且在運行時間不會顯示。
  • System.Windows.Forms.Timer,會引發事件並在一或多個事件接收中定期執行程式代碼的 Windows Forms元件。 元件沒有使用者介面,且設計用於單個線程環境;它會在UI線程上執行。
  • System.Web.UI.Timer (.NET Framework 只) ,ASP.NET 元件,會定期執行異步或同步網頁回傳。
  • System.Windows.Threading.DispatcherTimer,這是整合到佇列中的 Dispatcher 定時器。 此定時器會以指定的時間間隔,以指定的優先順序進行處理。

當您建立定時器時,可以指定要在方法第一次執行之前等候的時間量, (到期時間) ,以及在後續執行 (期間) 之間等候的時間量。 類別 Timer 的解析度與系統時鐘相同。 這表示如果期間小於系統時鐘的解析度,TimerCallback委派會以系統時鐘的解析度所定義的間隔執行,這大約是 Windows 7 和 Windows 8 系統上的 15 毫秒。 您可以使用 方法來變更到期時間和期間,或停用定時器 Change

注意

只要您使用 Timer,就必須保留其參考。 如同任何 Managed 對象,當沒有任何參考時, Timer 會受到垃圾收集。 仍然作用中的事實 Timer 不會防止收集它。

注意

所使用的系統時鐘與 GetTickCount 所使用的時鐘相同,不受 timeBeginPeriodtimeEndPeriod 所做的變更影響。

當不再需要定時器時,請使用 Dispose 方法來釋放定時器所持有的資源。 請注意,在呼叫 方法多載之後 Dispose() ,可能會發生回呼,因為定時器會佇列回呼供線程集區線程執行。 您可以使用 Dispose(WaitHandle) 方法多載等待所有回呼完成。

定時器所執行的回呼方法應該重新進入,因為它會在線程上 ThreadPool 呼叫。 如果定時器間隔小於執行回呼所需的時間,或是所有線程集區線程都正在使用中且回呼已排入佇列多次,則回呼可以在兩個線程集區線程上同時執行。

注意

System.Threading.Timer 是使用回呼方法且由線程集區線程提供服務的簡單輕量型定時器。 不建議搭配 Windows Forms 使用,因為其回呼不會發生在使用者介面線程上。 System.Windows.Forms.Timer是與 Windows Forms 搭配使用的較佳選擇。 針對伺服器型定時器功能,您可以考慮使用 System.Timers.Timer,這會引發事件並具有其他功能。

建構函式

Timer(TimerCallback)

以無限週期和無限到期時間初始化 Timer 類別的新執行個體,利用新建立 Timer 物件做為狀態物件。

Timer(TimerCallback, Object, Int32, Int32)

初始化 Timer 類別的新執行個體,使用 32 位元帶正負號的整數來指定時間間隔。

Timer(TimerCallback, Object, Int64, Int64)

初始化 Timer 類別的新執行個體,使用 64 位元帶正負號的整數來測量時間間隔。

Timer(TimerCallback, Object, TimeSpan, TimeSpan)

初始化 Timer 類別的新執行個體,使用 TimeSpan 值來測量時間間隔。

Timer(TimerCallback, Object, UInt32, UInt32)

初始化 Timer 類別的新執行個體,使用 32 位元不帶正負號的整數 (Unsigned Integer) 來測量時間間隔。

屬性

ActiveCount

取得目前有效的計時器數。 有註冊的有效計時器會在未來某個時間發出滴答聲,且尚未受到取消。

方法

Change(Int32, Int32)

變更開始的時間和計時器的方法引動過程之間的時間間隔,使用 32 位元帶正負號的整數來測量時間間隔。

Change(Int64, Int64)

變更開始的時間和計時器的方法引動過程之間的時間間隔,使用 64 位元帶正負號的整數來測量時間間隔。

Change(TimeSpan, TimeSpan)

變更開始的時間和計時器的方法引動過程之間的時間間隔,使用 TimeSpan 值來測量時間間隔。

Change(UInt32, UInt32)

變更開始的時間和計時器的方法引動過程之間的時間間隔,使用 32 位元不帶正負號的整數來測量時間間隔。

CreateObjRef(Type)

建立包含所有相關資訊的物件,這些資訊是產生用來與遠端物件通訊的所需 Proxy。

(繼承來源 MarshalByRefObject)
Dispose()

Timer 目前的執行個體所使用的資源全部釋出。

Dispose(WaitHandle)

Timer 目前的執行個體所使用的資源全部釋出,並當計時器已被處置時發出通知。

DisposeAsync()

Timer 目前的執行個體所使用的資源全部釋出。

Equals(Object)

判斷指定的物件是否等於目前的物件。

(繼承來源 Object)
Finalize()

允許物件在記憶體回收進行回收之前,嘗試釋放資源並執行其他清除作業。

GetHashCode()

做為預設雜湊函式。

(繼承來源 Object)
GetLifetimeService()
已淘汰.

擷取控制這個執行個體存留期 (Lifetime) 原則的目前存留期服務物件。

(繼承來源 MarshalByRefObject)
GetType()

取得目前執行個體的 Type

(繼承來源 Object)
InitializeLifetimeService()
已淘汰.

取得存留期服務物件,以控制這個執行個體的存留期原則。

(繼承來源 MarshalByRefObject)
MemberwiseClone()

建立目前 Object 的淺層複製。

(繼承來源 Object)
MemberwiseClone(Boolean)

建立目前 MarshalByRefObject 物件的淺層複本。

(繼承來源 MarshalByRefObject)
ToString()

傳回代表目前物件的字串。

(繼承來源 Object)

擴充方法

ConfigureAwait(IAsyncDisposable, Boolean)

設定如何執行從非同步可處置項目傳回的工作 await。

適用於

執行緒安全性

此型別具備執行緒安全。

另請參閱