C# Timer详解(c# timers.timer)
在C#编程中,Timer类是一个非常常用的工具,尤其适用于需要定期执行任务或者跟踪时间间隔的应用程序。C#中有三种不同的Timer类,它们分别位于不同的命名空间,且各有特点。下面将详细介绍这三种Timer类。
三种Timer类概述
1. System.Threading.Timer
- 执行机制:它是基于回调的方式来实现定时任务,在对象构造的时候启动,运行在线程池上,没有Start()和Stop()方法控制启动停止,需要使用Dispose()方法停止执行。构造函数参数列表为new Timer(new TimerCallback(callBack), 回调函数传参对象, 启动时间, 间隔时间) 。
- 效率与同步:执行时会每隔一段时间打开一个线程来执行TimerCallback里的操作,但不保证每个Timer对应的线程间的同步。就算把时间区间写成1毫秒,也还是要等到55毫秒才会执行下一个Timer 。
- 示例代码:
using System;
using System.Threading;
class Program
{
static Timer timer;
static int counter = 0;
static void Main()
{
// 创建一个Timer对象
timer = new Timer(Callback, null, 0, 1000);
// 让主线程等待一段时间,以便观察定时器的运行
Thread.Sleep(5000);
// 停止定时器
timer.Dispose();
}
static void Callback(object state)
{
counter++;
Console.WriteLine(#34;第 {counter} 次执行,当前时间: {DateTime.Now}");
}
}
2. System.Timers.Timer
- 执行机制:通过主线程创建,执行在线程池上,默认在不指定SynchronizingObject属性的情况下,不会卡住主界面。可以通过AutoReset = false设置只执行一次事件方法,自动重置默认为true,表示每次间隔结束后都会引发一次Elapsed事件,设置为false则仅在首次时间间隔后引发一次Elapsed事件 。
- 效率与选择:执行效率比System.Threading.Timer要好,是应用定时器时比较常用的选择 。
- 示例代码:
using System;
using System.Timers;
class Program
{
static Timer timer;
static int counter = 0;
static void Main()
{
// 创建一个Timer对象
timer = new Timer(1000); // 间隔为1000毫秒(即1秒)
timer.Elapsed += TimerElapsed;
timer.AutoReset = true; // 自动重置,每次间隔结束后都会触发事件
timer.Enabled = true; // 启用定时器
Console.WriteLine("按任意键停止定时器...");
Console.ReadKey();
// 停止定时器
timer.Stop();
}
static void TimerElapsed(object sender, ElapsedEventArgs e)
{
counter++;
Console.WriteLine(#34;第 {counter} 次执行,当前时间: {e.SignalTime}");
}
}
3.
System.Windows.Forms.Timer(仅在.Net Framework中)
- 执行机制:基于Windows消息循环,用事件方式触发,在界面线程执行,和它所在的Form属于同一个线程。Timer控件只有绑定了Tick事件和设置Enabled = true后才会自动计时,停止计时可以用Stop()方法控制,通过Stop()停止之后,如果想重新计时,可以用Start()方法来启动计时器 。
- 使用场景与问题:由于在界面线程执行,所以如果定时任务执行时间过长,会卡住UI界面。它是使用得比较多的Timer,常用于需要与界面交互的定时任务,比如更新界面上的时间显示等 。
- 示例代码:
在窗体应用程序中添加一个Timer控件timer1,在其Tick事件中编写如下代码:
private void timer1_Tick(object sender, EventArgs e)
{
this.toolStripStatusLabel3.Text = "系统当前时间: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
}
在Form的Load事件中对timer1进行相关设置:
private void MainForm_Load(object sender, EventArgs e)
{
timer1.Interval = 1000; // 设置时间间隔为1000毫秒(即1秒)
timer1.Enabled = true; // 启用定时器
}
三种Timer类的比较与选择
效率方面
System.Timers.Timer和
System.Windows.Forms.Timer执行时都是新开一个线程,所以执行效率比System.Threading.Timer要好 。
互操作性与稳定性
System.Windows.Forms.Timer互操作性差,且容易出错,因为它运行在界面线程,若任务耗时过长会导致界面卡顿;而System.Timers.Timer相对更稳定,因此在应用定时器时,一般会优先选择System.Timers.Timer 。
线程安全
对于System.Timers.Timer和System.Threading.Timer,由于它们是多线程执行,所以需要考虑线程安全问题。例如,当多个线程同时访问和修改共享资源时,可能会导致数据不一致。解决方案有两种:一是将共享资源的操作全部放在一个线程中执行(单线程);二是使用Lock()语句确保每次只有一个线程可以访问共享资源,其他线程需要等待该线程完成操作后才能继续执行 。
总结
C#中的Timer类提供了一种简单的方法来实现定时任务。通过合理选择不同的Timer类,并根据具体需求设置相应的属性和事件,可以满足各种定时任务的需求。在实际开发中,需要根据任务的特点和要求,综合考虑效率、线程安全、互操作性等因素,选择最合适的Timer类。