计时器

.NET 提供三个计时器,用于多线程环境:

注释

某些 .NET 实现可能包括其他计时器:

System.Threading.Timer 类

System.Threading.Timer 类使您可以按指定的时间间隔连续调用委托。 还可以使用此类在指定的时间间隔内计划对委托的单个调用。 委托在 ThreadPool 线程上执行。

创建 System.Threading.Timer 对象时,可以指定定义 TimerCallback 回调方法的委托、传递给回调的可选状态对象、回调第一次调用之前延迟的时间量以及回调调用之间的时间间隔。 若要取消挂起的计时器,请调用 Timer.Dispose 该方法。

以下示例创建一个计时器,该计时器在一秒(1000 毫秒)后首次调用提供的委托,然后每隔两秒调用一次。 示例中的状态对象用于计算调用委托的次数。 当委托被调用至少 10 次时,计时器停止。

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,通过调用false取消计时器则返回PeriodicTimer.DisposeWaitForNextTickAsync 可以选择性地接受一个 CancellationToken,当请求取消时,这将导致 TaskCanceledException

有关详细信息,请参阅 System.Threading.PeriodicTimer

另请参阅