计时器

.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,表示将按 Interval 属性定义的时间间隔定期引发 Elapsed 事件。

有关更多信息和示例,请参见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

另请参阅