C#.NET定时器类及使用方法

C#.NET 定时器类及使用方法

       在.net常用的定时器类有下面三种,使用定时器时需要设定参数,如间断时间、定时器计溢出后的回调函数、延时、开始等,定时器的的主要方法有开始、终止等,不同的定时器实现上述的方法会有一些差异,本文会针对具体的定时器一一举例说明。

 
  • 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,则使之不可用

System.Windows.Forms.Timer例程:

[csharp] view plain copy

print?

  1. using System.Windows.Forms;  
  2.   
  3. namespace WindowsFormsApplication1  
  4. {  
  5.     public partial class Form1 : Form  
  6.     {  
  7.         public Form1()  
  8.         {  
  9.             InitializeComponent();  
  10.         }  
  11.         //实例化一个timer  
  12.         System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();  
  13.           
  14.     private void StartTimeBtn_Click(object sender, EventArgs e)//开始计时  
  15.         {   
  16.             //给timer挂起事件  
  17.             myTimer.Tick  += new EventHandler(Callback);  
  18.             //使timer可用  
  19.             myTimer.Enabled = true;  
  20.             //设置时间间隔,以毫秒为单位  
  21.             myTimer.Interval = 1000;//1s  
  22.         }  
  23.         private void StopTimeBtn_Click(object sender, EventArgs e)//停止计时  
  24.         {  
  25.             //计时开始  
  26.             myTimer.Stop();  
  27.         }  
  28.         //回调函数  
  29.         private void Callback(object sender, EventArgs e)  
  30.         {   
  31.             //获取系统时间 20:16:16  
  32.             textBox1.Text = DateTime.Now.ToLongTimeString().ToString();  
  33.         }  
  34.     }  
  35. }  
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构造函数资料:

[csharp] view plain copy print ?
  1. public Timer(  
  2.     TimerCallback callback,   // TimerCallback 委托,表示要执行的方法。  
  3.     object state,         //一个包含回调方法要使用的信息的对象,或者为 null。  
  4.     int dueTime,    //调用 callback 之前延迟的时间量(以毫秒为单位)。  
  5.                     //指定 Timeout.Infinite 可防止启动计时器。  
  6.                     // 指定零 (0) 可立即启动计时器。  
  7.                     //指定零 (-1) 表示本定时器被禁用。  
  8.                     //Change(Int32,Int32)方法可以改写定时器参数  
  9.     int period  //如果 period 为零 (0) 或 -1 毫秒,而且dueTime 为正  
  10.                 //则只会调用一次 callback;  
  11.                 //然后计时器的定时行为将被禁用,使用 Change 可以改写定时器参数。  
  12. )  
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 可以改写定时器参数。
)

         https://msdn.microsoft.com/zh-cn/library/system.threading.timer(v=vs.110).aspx

2、编写timerCall回调函数

     格式:private  void  timerCall(object   xxxxx)  { …….; …….;}

3、使用Change(Int32,Int32)方法来修改定时器参数实现停止、重新开始等。

4、使用Dispose()方法释放定时器资源。

System.Threading.Timer例程:

[csharp] view plain copy

print?

  1. public startTimer()  
  2. {  
  3.   //定义一个对象  
  4.   System.Threading.Timer timer = new System.Threading.Timer(  
  5.     new System.Threading.TimerCallback(mytimer), null,  
  6.     0, 1000);//1S定时器  
  7. }  
  8.   
  9. //函数形式参数必须是object格式  
  10. public void mytimer(object a )  
  11. {  
  12.   Console.WriteLine(”你好”);  
  13. }  
    public startTimer() 

    { 

      //定义一个对象 

      System.Threading.Timer timer = new System.Threading.Timer( 

        new System.Threading.TimerCallback(mytimer), null, 

        0, 1000);//1S定时器 

    }
//函数形式参数必须是object格式
public void mytimer(object a )
{
  Console.WriteLine("你好");
}</pre>

三、 System.Timers.Timer类

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

System.Timers.Timer例程代码:

[csharp] view plain copy

print?

  1. System.Timers.Timer t = newSystem.Timers.Timer(5000); //设置时间间隔为5秒  
  2. private void Form1_Load(object sender,EventArgs e)  
  3. {  
  4.     t.Elapsed += newSystem.Timers.ElapsedEventHandler(Timer_TimesUp);  
  5.     t.AutoReset = false; //每到指定时间Elapsed事件是触发一次(false),还是一直触发(true)  
  6. }  
  7.   
  8. private void btnStart_Click(objectsender, EventArgs e)  
  9. {  
  10.     t.Enabled = true; //是否触发Elapsed事件  
  11.     t.Start();  
  12. }  
  13. private void Timer_TimesUp(objectsender, System.Timers.ElapsedEventArgs e)  
  14. {  
  15.     //到达指定时间5秒触发该事件输出 HelloWorld!!!!  
  16.     System.Diagnostics.Debug.WriteLine(”HelloWorld!!!!”);  
  17. }  
  18. private void btnStop_Click(objectsender, EventArgs e)  
  19. {  
  20.     t.Stop();  
  21.    System.Diagnostics.Debug.WriteLine(”未到指定时间5秒提前终结!!!”);  
  22. }  
        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秒提前终结!!!");
    }</pre>

  四、 System.Windows.Threading.DispatcherTimer类型(补充)

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

参考博客链接:

     http://www.cnblogs.com/DebugLZQ/archive/2012/08/05/2623669.html

     http://blog.csdn.net/luols/article/details/5880232

     http://www.360doc.com/content/11/0812/11/1039473_139824496.shtml

--------------------- 本文来自 在路上的工程师 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qq_40691189/article/details/80196492?utm_source=copy

猜你喜欢

转载自blog.csdn.net/lwjzjw/article/details/82898352