.NET 提供三个计时器,用于多线程环境:
- System.Threading.Timer,它将在 ThreadPool 线程上定期执行一个回调方法。
- System.Timers.Timer,默认情况下会在 ThreadPool 线程上定期引发事件。
- System.Threading.PeriodicTimer,使调用方可以在等待计时器的每一次滴答后执行工作。
注释
某些 .NET 实现可能包括其他计时器:
- System.Windows.Forms.Timer:定期触发事件的 Windows 窗体组件。 该组件没有用户界面,旨在用于单线程环境。
- System.Web.UI.Timer:ASP.NET 组件,定期执行异步或同步网页回发。
- System.Windows.Threading.DispatcherTimer:集成到队列中的 Dispatcher 计时器,该队列按指定的时间间隔和指定优先级进行处理。
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 设置为 false
。
AutoReset 属性的默认值是 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.Dispose。
WaitForNextTickAsync 可以选择性地接受一个 CancellationToken,当请求取消时,这将导致 TaskCanceledException。
有关详细信息,请参阅 System.Threading.PeriodicTimer。