C#.Net 定时器
如果需要定期重复执行一些方法,最容易的方式就是使用定时器。相比以下方式,定时器既方便使用又能高效地利用内存和资源。
new Thread(delegate ()
{
while (enabled)
{
DoSomeAction();
Thread.Sleep(TimeSpan.FromHours(24));
}
}).Start();
上述方式不仅永久占用了线程资源,而且如果不进行额外的编码,DoSomeAction每天的执行时间都会向后推延,定时器则解决了这些问题。
.NET Core提供了四种定时器,其中的两种定时器是通用多线程定时器:
- System.Threading.Timer
- System.Timers.Timer
另外两种则是特殊用途的单线程定时器:
- System.Windows.Forms.Timer(Windows Forms应用的定时器)
- System.Windows.Threading.DispatcherTimer(WPF的定时器)
多线程定时器更加强大,定时精确,使用灵活;对于定期更新Windows Forms或WPF界面元素的简单任务来说,单线程定时器更加安全方便。
多线程定时器
System.Threading.Timer是最简单的多线程定时器:它只有一个构造器和两个方法。
在下面的例子中,定时器会在第一个五秒钟结束后调用Tick方法,并输出“tick...”。而后每秒钟调用一次Tick方法,直至用户按下回车键:
static void Tick(object data)
{
Console.WriteLine(data);
}
static void Main(string[] args)
{
Timer tmr = new Timer(Tick, "tick...", 5000, 1000);
Console.ReadLine();
tmr.Dispose();
Console.ReadKey();
}
在创建定时器之后仍然可以调用Change
方法来修改定时器的定时间隔。如果希望定时器只触发一次,则可以用Timeout.Infinite
作为构造器的最后一个参数。
.NET Core在System.Timers命名空间中提供了另外一个同名定时器类。它简单包装了System.Threading.Timer,在相同底层引擎的基础上提供了额外的易用性。
static void tmr_Elapsed(object sender, EventArgs e)
{
Console.WriteLine("Tick");
}
static void Main(string[] args)
{
var tmr = new System.Timers.Timer(); // 不需要任何参数
tmr.Interval = 500;
tmr.Elapsed += tmr_Elapsed; // 使用事件而不是委托
tmr.Start(); // 开始
Console.ReadLine();
tmr.Stop(); // 停止
Console.ReadLine();
tmr.Start(); // 重启
Console.ReadLine();
tmr.Dispose(); // 销毁
Console.ReadKey();
}
多线程定时器会使用线程池来用有限的线程为多个定时器提供服务。因此,回调方法或者Elapsed事件每一次都可能在不同的线程上触发。此外,Elapsed事件几乎能够保证触发的时效性而不管前一次Elapsed事件是否执行完毕。因此,不论是回调委托还是事件处理器必须是线程安全的。
单线程定时器
.NET Core专门为WPF和Windows Forms应用程序提供了不需要考虑线程安全性的定时器。
这两种定时器的成员都和System.Timers.Timer的成员非常相似:Interval属性、Start和Stop方法(Tick事件和Elapsed事件是等价的);其使用方法也非常相似。但是它们内部的工作原理是不同的。
WPF与Windows Forms定时器并不会在线程池线程上触发定时器事件;而是将事件发送到WPF和Windows Forms消息循环中。这意味着Tick事件总会在创建定时器的线程上触发。而在一般应用程序中,这个线程也是用来管理所有用户界面元素和控件的线程。
WPF和Windows Forms定时器适用于执行细小的工作,通常用于更新UI的某一个部分(例如,显示时钟或者显示倒计时)。
本文来自博客园,作者:一纸年华,转载请注明原文链接:https://www.cnblogs.com/nullcodeworld/p/16645858.html