Timer 类

定义

提供以指定的时间间隔对线程池线程执行方法的机制。 此类不能被继承。

public ref class Timer sealed : IDisposable
public ref class Timer sealed : MarshalByRefObject, IAsyncDisposable, IDisposable
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, 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 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 IDisposable
继承
Timer
继承
属性
实现

示例

以下示例定义一个StatusChecker``CheckStatus类,该类包含其签名与TimerCallback委托相同的方法。 state该方法的参数CheckStatus是用于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 窗体组件,用于触发事件并在一个或多个事件接收器中定期执行代码。 该组件没有用户界面,设计用于单线程环境;它在 UI 线程上执行。
  • System.Web.UI.Timer (.NET Framework仅) ,ASP.NET 组件,定期执行异步或同步网页回发。
  • System.Windows.Threading.DispatcherTimer,集成到队列中的 Dispatcher 计时器。 此计时器在指定的时间间隔内使用指定的优先级进行处理。

创建计时器时,可以指定在方法首次执行之前等待的时间量 (到期时间) ,以及后续执行之间等待的时间量 (时间段) 。 类 Timer 的分辨率与系统时钟相同。 这意味着,如果时间段小于系统时钟的分辨率,TimerCallback则委托将以系统时钟分辨率定义的时间间隔执行,在Windows 7 和Windows 8系统上大约为 15 毫秒。 可以使用该方法更改截止日期和时间段,或禁用计时器 Change

备注

只要使用 a Timer,就必须保留对它的引用。 与任何托管对象一样,当没有对其引用时,会 Timer 受到垃圾回收的约束。 仍然处于活动状态的事实 Timer 不会阻止收集它。

备注

所使用的系统时钟与 GetTickCount 使用的时钟相同,不受 timeBeginPeriodtimeEndPeriod 所做的更改的影响。

不再需要计时器时,请使用 Dispose 该方法释放计时器持有的资源。 请注意,调用方法重载后 Dispose() 可能会发生回调,因为计时器将回调排队供线程池线程执行。 可以使用 Dispose(WaitHandle) 方法重载等待所有回调完成。

计时器执行的回调方法应重新进入,因为它在线程上 ThreadPool 调用。 如果计时器间隔小于执行回调所需的时间,或者所有线程池线程都正在使用且回调已多次排队,则可以在两个线程池线程上同时执行回调。

备注

System.Threading.Timer 是一个简单的轻型计时器,它使用回调方法,并由线程池线程提供服务。 不建议用于Windows 窗体,因为它的回调不会在用户界面线程上发生。 System.Windows.Forms.Timer是用于Windows 窗体的更好选择。 对于基于服务器的计时器功能,可以考虑使用 System.Timers.Timer,这会引发事件并具有其他功能。

构造函数

Timer(TimerCallback)

使用新创建的 Timer 对象作为状态对象,用一个无限周期和一个无限到期时间初始化 Timer 类的新实例。

Timer(TimerCallback, Object, Int32, Int32)

使用 32 位的有符号整数指定时间间隔,初始化 Timer 类的新实例。

Timer(TimerCallback, Object, Int64, Int64)

用 64 位有符号整数来度量时间间隔,以初始化 Timer 类的新实例。

Timer(TimerCallback, Object, TimeSpan, TimeSpan)

初始化 Timer 类的新实例,使用 TimeSpan 值来度量时间间隔。

Timer(TimerCallback, Object, UInt32, UInt32)

用 32 位无符号整数来度量时间间隔,以初始化 Timer 类的新实例。

属性

ActiveCount

获取当前活动的计时器计数。 活动计数器注册为在未来某一时间点进行计时且尚未取消。

方法

Change(Int32, Int32)

更改计时器的启动时间和方法调用之间的间隔,用 32 位有符号整数度量时间间隔。

Change(Int64, Int64)

更改计时器的启动时间和方法调用之间的间隔,用 64 位有符号整数度量时间间隔。

Change(TimeSpan, TimeSpan)

更改计时器的启动时间和方法调用之间的时间间隔,使用 TimeSpan 值度量时间间隔。

Change(UInt32, UInt32)

更改计时器的启动时间和方法调用之间的间隔,用 32 位无符号整数度量时间间隔。

CreateObjRef(Type)

创建一个对象,该对象包含生成用于与远程对象进行通信的代理所需的全部相关信息。

(继承自 MarshalByRefObject)
Dispose()

释放由 Timer 的当前实例使用的所有资源。

Dispose(WaitHandle)

释放 Timer 的当前实例使用的所有资源并在释放完计时器时发出信号。

DisposeAsync()

释放由 Timer 的当前实例使用的所有资源。

Equals(Object)

确定指定对象是否等于当前对象。

(继承自 Object)
Finalize()

在垃圾回收将某一对象回收前允许该对象尝试释放资源并执行其他清理操作。

GetHashCode()

作为默认哈希函数。

(继承自 Object)
GetLifetimeService()
已过时。

检索控制此实例的生存期策略的当前生存期服务对象。

(继承自 MarshalByRefObject)
GetType()

获取当前实例的 Type

(继承自 Object)
InitializeLifetimeService()
已过时。

获取生存期服务对象来控制此实例的生存期策略。

(继承自 MarshalByRefObject)
MemberwiseClone()

创建当前 Object 的浅表副本。

(继承自 Object)
MemberwiseClone(Boolean)

创建当前 MarshalByRefObject 对象的浅表副本。

(继承自 MarshalByRefObject)
ToString()

返回表示当前对象的字符串。

(继承自 Object)

扩展方法

ConfigureAwait(IAsyncDisposable, Boolean)

配置如何执行从异步可处置项返回的任务的等待。

适用于

线程安全性

此类型是线程安全的。

另请参阅