0%

C#定时器详解

定时器

在.NET Framework中存在着4种定时器,其中分为两类: 多线程计时器 和 特殊目的的单线程计时器

1. 多线程计时器

1.1 System.Threading.Timer

1.2 System.Timers.Timer

2. 特殊目的的单线程计时器

2.1 System.Windows.Forms.Timer(Windows Forms Timer)

2.2 System.Windows.Threading.DispatcherTimer(WPF timer)

1. 多线程计时器

多线程计时器比较强大,精确,而且可扩展性强;

1.1 System.Threading.Timer

System.Threading.Timer是最简单的多线程计时器。

在下面的例子中,定时器在5秒后开始定时1秒的调用Tick方法。

1
2
3
4
5
6
7
8
9
10
11
public static void Main ()
{
//5秒后开始运行,接着每隔1秒的调用Tick方法
Timer tmr = new Timer(Tick, "tick...", 5000, 1000);
Console.ReadLine();
tmr.Dispose();
}
static void Tick(object data)
{
Console.WriteLine(data);
}
1.2 System.Timers.Timer

System.Timers.Timer对System.Threading.Timer进行了简单包装,增加了下面几个特性:

  • 实现了Component, 所以可以在设计器显示。

    工具箱 => 右键 => 选择项,在弹出的 选择工具箱项 中的 .NET Framework组件 中查找 System.Timers 命名空间下的 Timer,添加即可。

  • 代替Change方法的一个Interval属性
  • 代替callback委托的一个Elapsed事件
  • 启动和停止timer的Enabled属性,默认是false。
  • 为了避免Enabled造成混乱,提供了Start和Stop方法。
  • 是否在每次指定的间隔结束时引发Elapsed时间,还是仅间隔第一次结束后运行的AutoReset属性。
  • 在WPF或Windows Forms中安全的调用方法的SynchronizingObject对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void MainThread()
{
Timer tmr = new Timer();
tmr.Interval = 500;
//设置是执行一次(false)还是一直执行(true);
//tmr.AutoReset = true;
tmr.Elapsed += new ElapsedEventHandler(tmr_Elapsed);
tmr.Start();
Console.ReadLine();
tmr.Stop();
Console.ReadLine();
tmr.Start();
Console.ReadLine();
tmr.Dispose();
}

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

2. 单线程计时器

  • 单线程计时器比较安全,对于更新 Windows Forms controls或者WPF这种简单任务来说更方便。
  • 单线程计时器是被设计成属于他们执行环境的计时器,如果你在一个Windows服务应用程序中使用Windows Forms的Timer,timer 事件并不会被触发,只有在对应的环境下才会被触发。
  • 像System.Timers.Timer一样,他们也提供了相同的成员(Interval,Tick,Start,Stop),但是他们内部的工作原理不同:

    WPF 和 Windows Forms 的计时器使用 消息循环机制 来取代 线程池产生消息的机制
    这意味着Tick事件总是在创建timer的那个线程上执行,同时也意味着如果上一个Tick消息还未被处理,即使时间超过了间隔时间,在消息循环中也只存在一个Tick消息。

  • 你可以忘记线程安全。

    一个Tick事件在前一个Tick事件被处理完毕前不会被触发。

  • 你可以直接在Tick事件处理代码中更新控件,不需要调用Control.Invoke或Dispatcher.Invoke.

参考: