前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[C#]多线程定时器

[C#]多线程定时器

作者头像
科控物联
发布2022-03-29 16:31:33
9840
发布2022-03-29 16:31:33
举报
文章被收录于专栏:科控自动化

System.Threading.Timer是最简单的多线程定时器:它只有一个构造器和两个方法(尤其适合于像作者这样的极简主义者!)。在接下来的例子中,定时器会在第一个五秒钟结束后调用Tick方法,并输出“tick…”。而后每一秒钟调用一次Tick方法,直至用户按下回车键:

代码语言:javascript
复制
using System;
using System.Threading;


class Program
{
  static void Main()
  {
    // First interval = 5000ms; subsequent intervals = 1000ms
    Timer tmr = new Timer (Tick, "tick...", 5000, 1000);
    Console.ReadLine();
    tmr.Dispose();         // This both stops the timer and cleans up.
  }


  static void Tick (object data)
  {
    // This runs on a pooled thread
    Console.WriteLine (data);          // Writes "tick..."
  }
}

12.5.1节中介绍了如何销毁一个多线程定时器。

在创建定时器之后仍然可以调用Change方法修改定时器的定时间隔。如果希望定时器只触发一次,则可以用Timeout.Infinite作为构造器的最后一个参数。

.NET Framework在System.Timers命名空间中提供了另外一个同名定时器类。它简单包装了System.Threading.Timer,在相同底层引擎的基础上提供了额外的易用性。以下总结了它的附加功能:

·实现了IComponent接口,允许嵌入到Visual Studio设计器的组件托盘中。

·提供了Interval属性替代Change方法。

·提供了Elapsed事件取代回调委托。

·提供了Enabled属性来开始和停止计时器(默认值为false)。

·如果不习惯使用Enabled属性还可以使用Start和Stop方法。

·提供了AutoReset标志,用于指示重复的事件(默认值为true)。

·提供了SynchronizingObject属性。可调用该对象的Invoke和BeginInvoke方法安全地调用WPF元素和Windows Forms控件的方法。

例如:

代码语言:javascript
复制
using System;
using System.Timers;   // Timers namespace rather than Threading
class SystemTimer
{
  static void Main()
  {
    Timer tmr = new Timer();       // Doesn't require any args
    tmr.Interval = 500;
    tmr.Elapsed += tmr_Elapsed;    // Uses an event instead of a delegate
    tmr.Start();                   // Start the timer
    Console.ReadLine();
    tmr.Stop();                    // Stop the timer
    Console.ReadLine();
    tmr.Start();                   // Restart the timer
    Console.ReadLine();
    tmr.Dispose();                 // Permanently stop the timer
  }

  static void tmr_Elapsed (object sender, EventArgs e)
  {
    Console.WriteLine ("Tick");
  }
}

多线程定时器会使用线程池来用有限的线程为多个定时器提供服务。因此,回调方法或者Elapsed事件每一次都可能在不同的线程上触发。此外,Elapsed事件几乎能够保证触发的时效性而不管前一次Elapsed事件是否执行完毕。因此,不论是回调委托还是事件处理器必须是线程安全的。

多线程的定时器精度取决于操作系统,一般情况下精度在10到20毫秒范围内。如果需要更高的精度,则可以使用原生的互操作并调用Windows的多媒体定时器。多媒体定时器定义在winmm.dll中,且其精度接近1毫秒。首先调用timeBeginPeriod通知操作系统提高定时精度,然后调用timeSetEvent方法启动一个多媒体定时器。当使用完毕之后,调用timeKillEvent停止定时器,并调用timeEndPeriod通知操作系统不再需要提高定时精度了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 科控物联 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档