C# 中的定时器类型

文章转自:http://www.cnblogs.com/DebugLZQ/archive/2012/08/05/2623669.html 

定时器是系统常用的组件之一,程序员可以根据自己的需求定制一个定时器类型,也可以使用.net内建的定时器类型。在.net中一共为程序员提供了3种定时器。

  1. System.Windows.Forms.Timer类
  2. System.Threading.Timer类
  3. System.Timers.Timer类

一、System.Windows.Forms.Timer
  从这个定时器的命名空间可以看出,.net设计这个定时器的目的是为了方便程序员在Window Form中使用的定时器。当一个System.Windows.Forms.Timer类被构造时,当前定时器会和当前线程进行关联。而当计时器的计满后,一个定时器消息将被插入到当前线程的消息队列中。当前线程逐一处理消息中的所有消息,并一一派发给各自的处理方法。这样的机制和利用工作者进程定时有很大的区别,System.Windows.Forms.Timer类型并没有涉及多线程的操作,定时器的设置、定时方法的执行都在同一个线程之上。这就意味着System.Windows.Forms.Timer并不能准确计时,尤其当消息阻塞时,定时器的误差将会更大,因为定时器消息只能等待在前面的所有消息处理完后才能得到处理。但是因为System.Windows.Forms.Timer类型的定时器并不涉及多线程的操作,因此是线程安全的,不会发生回调方法重入的问题。  

   主要使用步骤如下:

  1. System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();//实例化 
  2. myTimer.Tick += new EventHandler(函数名); //给timer挂起事件
  3. myTimer.Enabled = true;//使timer可用
  4. myTimer.Interval = n; //设置时间间隔,以毫秒为单位
  5. myTimer.Stop(); //如果要暂停计时则使用Stop()方法
  6. myTimer.Enabled = false;//若要停止使用timer,则使之不可用
using System.Windows.Forms;  
  
namespace WindowsFormsApplication1  
{  
    public partial class Form1 : Form  
    {  
        public Form1()  
        {  
            InitializeComponent();  
        }  
        //实例化一个timer  
        System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();  
          
        private void StartTimeBtn_Click(object sender, EventArgs e)//开始计时  
        {   
            //给timer挂起事件  
            myTimer.Tick  += new EventHandler(Callback);  
            //使timer可用  
            myTimer.Enabled = true;  
            //设置时间间隔,以毫秒为单位  
            myTimer.Interval = 1000;//1s  
         }  
        private void StopTimeBtn_Click(object sender, EventArgs e)//停止计时  
        {  
            //计时开始  
            myTimer.Stop();  
        }  
        //回调函数  
        private void Callback(object sender, EventArgs e)  
        {   
            //获取系统时间 20:16:16  
            textBox1.Text = DateTime.Now.ToLongTimeString().ToString();  
        }  
    }  
} 

 

二、System.Threading.Timer

  这个定时器类的使用相对复杂,但同时它也是最优化的一个定时器类型。System.Threading.Timer的定时方法在独立的线程上执行,定时时间更为准确。所有的对象有一个线程控制,当下一个定时到达时,该线程会负责在线程中获得一个新的工作者线程,用以执行相应的回调方法。虽然这个定时器是相对最优化的一个定时器类型,但是从其机制上来讲,其并不是线程安全的,可能会出现回调方法重入的问题。解释下方法重入,是一个有关多线程编程的概念,意思大概是:同一程序中,多个线程同时运行时,就可能发生同一个方法被多个进程同时调用的情况。当这个方法中存在一些非线程安全的代码时,方法重入会导致数据发生同步错误的bug。
      主要使用步骤如下:
1、实例构造一个线程定时器。
     System.Threading.Timer  mytimer =  
         new System.Threading.Timer(new  System.Threading.TimerCallback(timerCall), null, 0, 1000);
timer构造函数资料:
 public Timer(
    TimerCallback callback,   // TimerCallback 委托,表示要执行的方法。
    object state,         //一个包含回调方法要使用的信息的对象,或者为 null。
    int dueTime,    //调用 callback 之前延迟的时间量(以毫秒为单位)。
                           //指定 Timeout.Infinite 可防止启动计时器。
                          // 指定零 (0) 可立即启动计时器。
                         //指定零 (-1) 表示本定时器被禁用。
                        //Change(Int32,Int32)方法可以改写定时器参数
    int period  //如果 period 为零 (0) 或 -1 毫秒,而且dueTime 为正
                    //则只会调用一次 callback;
                    //然后计时器的定时行为将被禁用,使用 Change 可以改写定时器参数。
)
2、编写timerCall回调函数
     格式:private  void  timerCall(object   xxxxx)  { .......; .......;}
3、使用Change(Int32,Int32)方法来修改定时器参数实现停止、重新开始等。
4、使用Dispose()方法释放定时器资源。

using System;
using System.Threading;

class TimerExample
{
    static void Main()
    {
        // Create an event to signal the timeout count threshold in the
        // timer callback.
        AutoResetEvent autoEvent     = new AutoResetEvent(false);

        StatusChecker  statusChecker = new StatusChecker(10);

        // Create an inferred delegate that invokes methods for the timer.
        TimerCallback tcb = statusChecker.CheckStatus;

        // Create a timer that signals the delegate to invoke 
        // CheckStatus after one second, and every 1/4 second 
        // thereafter.
        Console.WriteLine("{0} Creating timer.\n", 
            DateTime.Now.ToString("h:mm:ss.fff"));
        Timer stateTimer = new Timer(tcb, autoEvent, 1000, 250);

        // When autoEvent signals, change the period to every
        // 1/2 second.
        autoEvent.WaitOne(5000, false);
        stateTimer.Change(0, 500);
        Console.WriteLine("\nChanging period.\n");

        // When autoEvent signals the second time, dispose of 
        // the timer.
        autoEvent.WaitOne(5000, false);
        stateTimer.Dispose();
        Console.WriteLine("\nDestroying timer.");
    }
}

class StatusChecker
{
    private int invokeCount;
    private int  maxCount;

    public StatusChecker(int count)
    {
        invokeCount  = 0;
        maxCount = count;
    }

    // This method is called by the timer delegate.
    public void CheckStatus(Object stateInfo)
    {
        AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
        Console.WriteLine("{0} Checking status {1,2}.", 
            DateTime.Now.ToString("h:mm:ss.fff"), 
            (++invokeCount).ToString());

        if(invokeCount == maxCount)
        {
            // Reset the counter and signal Main.
            invokeCount  = 0;
            autoEvent.Set();
        }
    }
}


三、 System.Timers.Timer类

  这是一个相对较旧的类型,它和System.Threading.Timer一样,可以由工作者线程来执行回调方法,但同时它也可以在IDE环境中被拖到窗体控件上,这个时候它的行为非常类似于System.Windows.Forms.Timer类型,在消息过多时其定时并不准确。  
System.Timers.Timer可以视为System.Threading.Timer的一个包装,其类型设计相对古老,不建议使用该定时器。
System.Timers.Timer例程代码:

        System.Timers.Timer t = newSystem.Timers.Timer(5000); //设置时间间隔为5秒
        private void Form1_Load(object sender,EventArgs e)
        {
            t.Elapsed += newSystem.Timers.ElapsedEventHandler(Timer_TimesUp);
            t.AutoReset = false; //每到指定时间Elapsed事件是触发一次(false),还是一直触发(true)
        }
        
        private void btnStart_Click(objectsender, EventArgs e)
        {
            t.Enabled = true; //是否触发Elapsed事件
            t.Start();
        }
        private void Timer_TimesUp(objectsender, System.Timers.ElapsedEventArgs e)
        {
            //到达指定时间5秒触发该事件输出 HelloWorld!!!!
            System.Diagnostics.Debug.WriteLine("HelloWorld!!!!");
        }
        private void btnStop_Click(objectsender, EventArgs e)
        {
            t.Stop();
           System.Diagnostics.Debug.WriteLine("未到指定时间5秒提前终结!!!");
        }

  四、 System.Windows.Threading.DispatcherTimer类型(补充)
  System.Windows.Threading.DispatcherTimer集成到按指定时间间隔和指定优先级处理的 Dispatcher 队列中的计时器。因为 DispatcherTimer 操作与其他操作一样被放置到Dispatcher队列中,何时执行DispatcherTimer 操作取决于队列中的其他作业及其优先级,因此它不能保证会正好在时间间隔发生时执行计时器,但能够保证不会在时间间隔发生之前执行计时器。如果 System.Timers.Timer 用于 WPF 应用程序,则值得注意的是 System.Timers.Timer 运行于不同于user interface(UI) 线程的其他线程上。 为了访问userinterface (UI) 线程上的对象,需要使用 Invoke 或 BeginInvoke 将操作发布到user interface (UI) 线程的 Dispatcher 上。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值