計時器

.NET 提供三種計時器,可用於多執行緒環境:

注意

某些 .NET 實作可能會包含其他計時器:

System.Threading.Timer 類別

System.Threading.Timer 類別可讓您依指定的時間間隔連續呼叫委派。 您也可以使用此類別,排程單一委派呼叫依指定時間間隔執行。 委派是在 ThreadPool 執行緒上執行。

當您建立 System.Threading.Timer 物件時,您會指定定義回呼方法的 TimerCallback 委派、傳遞至回呼的選擇性狀態物件、第一個回呼引動過程之前延遲的時間量,以及回呼引動過程之間的時間間隔。 若要取消擱置中的計時器,請呼叫 Timer.Dispose 方法。

下列範例會建立計時器,在一秒 (1000 毫秒) 後第一次呼叫提供的委派,然後每隔兩秒呼叫一次。 範例中的狀態物件可用來計算呼叫委派的次數。 計時器會在委派至少呼叫 10 次時停止。

using namespace System;
using namespace System::Threading;

ref class TimerState
{
public:
    int counter;
};

ref class Example
{
private:
    static Timer^ timer;

public:
    static void TimerTask(Object^ state)
    {
        Console::WriteLine("{0:HH:mm:ss.fff}: starting a new callback.", DateTime::Now);

        TimerState^ timerState = dynamic_cast<TimerState^>(state);
        Interlocked::Increment(timerState->counter);
    }

    static void Main()
    {
        TimerCallback^ tcb = gcnew TimerCallback(&TimerTask);
        TimerState^ state = gcnew TimerState();
        state->counter = 0;
        timer = gcnew Timer(tcb, state, 1000, 2000);

        while (state->counter <= 10)
        {
            Thread::Sleep(1000);
        }

        timer->~Timer();
        Console::WriteLine("{0:HH:mm:ss.fff}: done.", DateTime::Now);
    }
};

int main()
{
    Example::Main();
}
using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    private static Timer timer;

    static void Main(string[] args)
    {
        var timerState = new TimerState { Counter = 0 };

        timer = new Timer(
            callback: new TimerCallback(TimerTask),
            state: timerState,
            dueTime: 1000,
            period: 2000);

        while (timerState.Counter <= 10)
        {
            Task.Delay(1000).Wait();
        }

        timer.Dispose();
        Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: done.");
    }

    private static void TimerTask(object timerState)
    {
        Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: starting a new callback.");
        var state = timerState as TimerState;
        Interlocked.Increment(ref state.Counter);
    }

    class TimerState
    {
        public int Counter;
    }
}
Imports System.Threading

Module Program

    Private Timer As Timer

    Sub Main(args As String())

        Dim StateObj As New TimerState
        StateObj.Counter = 0

        Timer = New Timer(New TimerCallback(AddressOf TimerTask), StateObj, 1000, 2000)

        While StateObj.Counter <= 10
            Task.Delay(1000).Wait()
        End While

        Timer.Dispose()
        Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: done.")
    End Sub

    Private Sub TimerTask(ByVal StateObj As Object)

        Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: starting a new callback.")

        Dim State As TimerState = CType(StateObj, TimerState)
        Interlocked.Increment(State.Counter)
    End Sub

    Private Class TimerState
        Public Counter As Integer
    End Class
End Module

如需詳細資訊與範例,請參閱System.Threading.Timer

System.Timers.Timer 類別

可用於多執行緒環境的另一個計時器是 System.Timers.Timer,預設會在 ThreadPool 上引發事件。

建立 System.Timers.Timer 物件時,您可以指定要引發 Elapsed 事件的時間間隔。 使用 Enabled 屬性指出計時器是否應該引發 Elapsed 事件。 如果您需要 Elapsed 事件只在經過指定的間隔之後才引發,請將 AutoReset 設定為 falseAutoReset 屬性的預設值為 true,表示 Elapsed 事件會依 Interval 屬性定義的間隔定期引發。

如需詳細資訊與範例,請參閱System.Timers.Timer

System.Threading.PeriodicTimer 類別

System.Threading.PeriodicTimer 類別可讓您等候指定間隔刻度、在呼叫 PeriodicTimer.WaitForNextTickAsync 之後執行工作。

當您建立 System.Threading.PeriodicTimer 物件時,便會指定 TimeSpan 以決定計時器每個刻度之間的時間長度。 您會直接在範圍內執行工作並等候 WaitForNextTickAsync 以依指定的間隔前移計時器,而不是如同先前計時器類別一樣傳遞回呼或設定事件處理常式。

WaitForNextTickAsync 方法會傳回 ValueTask<bool>;在成功引發計時器時傳回 true,在呼叫 PeriodicTimer.Dispose 來取消計時器時傳回 falseWaitForNextTickAsync 會選擇性接受 CancellationToken,這會在要求取消時產生 TaskCanceledException

如需詳細資訊,請參閱System.Threading.PeriodicTimer

另請參閱