科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件.NET框架类库中的定时器类的使用

.NET框架类库中的定时器类的使用

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

不论在客户端应用程序还是服务器组件(包括窗口服务)定时器通常扮演一个重要的角色。

作者:Alex Calvo 来源:论坛整理 2007年11月19日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
除了标准的EventArgs成员,ElapsedEventArgs类暴露了一个公共的SignalTime属性,它包含了一个精确的定时器时间片消失的时间。因为这个类支持不同线程的访问,除了时间消失事件所在的线程,应该相信它的Stop方法能够被其它线程所调用。这会潜在的导致消失事件被引发即使其Stop方法已经被调用。你可以把SignalTime和Stop方法调用的时间进行比较来解决这个问题。

  System.Timers.Timer也提供了AutoReset属性来决定当时间片消失事件引发后是继续进行还是只这一次。要记住在定时器开始后重设间隔属性会导致当前计数为0。比如,设置了一个5秒的间隔,在间隔被改变为10秒时3秒已经过去了,那么下一个定时器事件将会在上一个定时器事件13秒后发生。

以下是引用片段:
  System.Threading.Timer

  第三个定时器类来自System.Threading名字空间。我愿意说这是所有定时器类中最好的一个,但这会引起误导。举一个例子,我惊讶的发现对于驻留在System.Threading名字空间的这个类天生就不是线程安全的。(很明显,这不意味着它不能以线程安全的方式使用)。这个类的可编程接口同其它两个类也不一致,它稍微有点麻烦。

  不像我开始描述的两个定时器类,System.Threading.Timer有四个重载构造函数,就像下面这样:

以下是引用片段:
public Timer(TimerCallback callback, object state, long dueTime, long period);

public Timer(TimerCallback callback, object state, UInt32 dueTime, UInt32 period);

public Timer(TimerCallback callback, object state, int dueTime, int period);

public Timer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period);

  第一个参数(callback)要求一个TimerCallback的委托,它指向一个方法,该方法具有下面的结构:

以下是引用片段:
  public void TimerCallback(object state);

  第二个参数(state)可以为空或者是包含程序规范信息的对象。在每一个定时器事件被调用时该state对象作为一个参数传递给你的定时回调函数。记住定时回调功能是在一个工作者线程上执行的,所以你必须确保访问state对象的线程安全。

  第三个参数(dueTime)让你定义一个引发初始定时器事件的时间。你可指定一个0立即开始定时器或者阻止定时器自动的开始,你可以使用System.Threading.Timeout.Infinite常量。

  第四个参数(period)让你定义一个回调函数被调用的时间间隔(毫秒)。给该参数定义一个0或者Timeout.Infinite可以阻止后续的定时器事件调用。

  一旦构造函数被调用,你仍然可以通过Change方法改变dueTime和period。该方法有下面四种重载形式:

  public bool Change(int dueTime, int period);public bool Change(uint dueTime, uint period);public bool Change(long dueTime, long period);public bool Change(TimeSpan dueTime, TimeSpan period);

  下面是我在例子程序中用到的开始和停止该定时器的代码:

以下是引用片段:
//Initialize the timer to not start automatically...System.Threading.Timer tmrThreadingTimer = newSystem.Threading.Timer(new TimerCallback(tmrThreadingTimer_TimerCallback), null, System.Threading.Timeout.Infinite, 1000);

//Manually start the timer...tmrThreadingTimer.Change(0, 1000);

//Manually stop the timer...tmrThreadingTimer.Change(Timeout.Infinte, Timeout.Infinite);

  正如你所期望的那样,通过选择System.Threading.Timer类运行例子程序会产生同你看到的System.Timers.Timer类一样的输出结果。因为TimerCallback功能也是在工作者线程上被调用,没有一个跳动被跳过(假设有工作者线程可用)。Figure 5显示了例子程序的输出结果。

  不像System.Timers.Timer类,没有与SynchronizingObject相对应的属性被提供。任何请求访问UI控件的操作都必须通过控件的Invoke或BeginInvoke方法被列集

  定时器的线程安全编程

  为了最大限度的代码重用,三种不同类型的定时器事件都调用了同样的ShowTimerEventFired方法,下面就是三个定时器事件的处理函数:

以下是引用片段:
private void tmrWindowsFormsTimer_Tick(object sender, System.EventArgse)

ShowTimerEventFired(DateTime.Now, GetThreadName());

}

private void tmrTimersTimer_Elapsed(object sender, System.TimersElapsedEventArgse){

 ShowTimerEventFired(DateTime.Now, GetThreadName());

}

private void tmrThreadingTimer_TimerCallback(object state){ ShowTimerEventFired(DateTime.Now, GetThreadName());}

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章