C#四种计时器Timer的区别和用法

作者:springsnow 时间:2021-10-12 01:31:14 

1、System.Threading.Timer 线程计时器

1、最底层、轻量级的计时器。基于线程池实现的,工作在辅助线程。

2、它并不是内在线程安全的,并且使用起来比其他计时器更麻烦。此计时器通常不适合 Windows 窗体环境。

构造函数:public Timer(TimerCallback callback, object state, int dueTime, int period);

string state=”.”;
//state参数可以传入想在callback委托中处理的对象。可以传递一个AutoRestEvent,在回调函数中向主函数发送信号。
Timer timer=new Timer(TimeMethod,state,100,1000)//100表示多久后开始,1000表示隔多久执行一次。

void TimerMethod(object state)
{Console.Write(state.ToString());}

timer.Dispose();//取消timer执行

2、System.Timers.Timer  服务器计时器

1、针对服务器的服务程序,基于System.Threading.Timer,被设计并优化成能用于多线程环境。在这种情况下,应该确保事件处理程序不与 UI 交互。在asp.net中一般使用System.Timers.Timer。

2、继承自Compnent,公开了可以SynchronizingObject 属性,避免了线程池中无法访问主线程中组件的问题(模拟System.Windows.Forms.Timer单线程模式)。但是除非需要对事件的时间安排进行更精确的控制,否则还是应该改为使用 System.Windows.Forms.Timer。

3、AutoReset属性设置计时器是否在引发Elapsed事件后重新计时,默认为true。如果该属性设为False,则只执行timer_Elapsed方法一次。

4、System.Timers.Timer是多线程定时器,如果一个Timer没有处理完成,到达下一个时间点,新的Timer同样会被启动。所以,Timer比较适合执行不太耗时的小任务,若在Timer中运行耗时任务,很容易出现由于超时导致的多线程重入问题,即多个线程同时进入timer_Elapsed方法。

System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 500;
timer.SynchronizingObject = this;

timer.Elapsed+=new System.Timers.ElapsedEventHandler(timer_Elapsed);

timer.Start(); private void timer_Elapsed(Object source, Timers.ElapsedEventArgs e)
{
   this.tbTimer.Text = value;
}

5、为了应对多线程重入问题。可以加锁,也可以增加标志位。 Interlocked.Exchange提供了一种轻量级的线程安全的给对象赋值的方法,所以使用Interlocked.Exchange给变量赋值。

int inTimer = 0;
       void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
       {
           if (Interlocked.Exchange(ref inTimer, 1) == 0)
           {
               Thread.Sleep(3000);
               string currentThreadId = Thread.CurrentThread.ManagedThreadId.ToString();
               this.Dispatcher.BeginInvoke(new Action(() =>
               {
                   this.Label_Result.Content += currentThreadId + ",";
               }), null);
               Interlocked.Exchange(ref inTimer, 0);
           }
       }

3、System.Windows.Forms.Timer  Windows计时器

此计时器直接继承自Component,它经过了专门的优化以便与 Windows 窗体一起使用,并且必须在窗口中使用。

  • Windows计时器建立在基于消息的UI线程上运行,精度限定为5ms。Tick事件中执行的事件与主窗体是同一个线程(单线程),并且对与 UI 交互是安全的。

  • 只有Enable和Internal两个属性和一个Tick事件,可以使用Start()和Stop()方法控制Enable属性。

using System.Windows.Forms;

public Form1()
{
   InitializeComponent();
   this.Load += delegate
   {
       Timer timer = new Timer();
       timer.Interval = 500;
       timer.Tick += delegate
       {
           System.Diagnostics.Debug.WriteLine($"Timer Thread: {System.Threading.Thread.CurrentThread.ManagedThreadId}");
           System.Diagnostics.Debug.WriteLine($"Is Thread Pool: {System.Threading.Thread.CurrentThread.IsThreadPoolThread}");
           this.lblTimer.Text = DateTime.Now.ToLongTimeString();
       };

timer.Start();
       System.Diagnostics.Debug.WriteLine($"Main Thread: {System.Threading.Thread.CurrentThread.ManagedThreadId}");
   };
}

4. System.Windows.Threading.DispatcherTimer

主要用于WPF中。属性和方法与System.Windows.Forms.Timer类似。DispatcherTimer中Tick事件执行是在主线程中进行的。

使用DispatcherTimer时有一点需要注意,因为DispatcherTimer的Tick事件是排在Dispatcher队列中的,当系统在高负荷时,不能保证在Interval时间段执行,可能会有轻微的延迟,但是绝对可以保证Tick的执行不会早于Interval设置的时间。如果对Tick执行时间准确性高可以设置DispatcherTimer的priority。

来源:https://www.cnblogs.com/springsnow/p/9435696.html

标签:C#,计时器,Timer
0
投稿

猜你喜欢

  • java实现银行ATM管理系统

    2023-10-30 14:50:51
  • java实现微信扫码支付功能

    2023-11-09 18:38:08
  • spring boot devtools在Idea中实现热部署方法

    2023-07-20 02:31:25
  • 谈谈Java中自定义注解及使用场景

    2022-08-28 04:45:39
  • 详解JAVA中的OPTIONAL

    2022-08-22 17:09:04
  • 详解SpringCloud Ribbon 负载均衡通过服务器名无法连接的神坑

    2021-06-01 07:28:41
  • Java线程状态变换过程代码解析

    2023-08-06 18:05:29
  • linux下C语言中的mkdir函数与rmdir函数

    2023-07-07 14:16:16
  • IDEA 2020 本土化,真的是全中文了(真香)

    2023-11-25 08:02:58
  • Spring Boot Admin实践详解

    2023-08-25 06:57:53
  • Java利用for循环打印菱形的实例教程

    2021-08-16 14:18:44
  • 剖析Java中阻塞队列的实现原理及应用场景

    2023-09-01 17:33:07
  • Struts2学习笔记(5)-参数传递方法

    2023-08-30 13:03:21
  • 如何创建SpringBoot项目

    2022-03-26 16:06:37
  • Java中OAuth2.0第三方授权原理与实战

    2021-09-27 01:48:57
  • 教你开发脚手架集成Spring Boot Actuator监控的详细过程

    2021-11-19 03:27:39
  • java中的JsonSerializer用法,前后端单位转换必备

    2022-05-01 07:58:48
  • Java超详细分析泛型与通配符

    2023-07-28 08:34:26
  • java 实现文件复制和格式更改的实例

    2023-10-21 08:07:49
  • JAVA 内存溢出案例汇总

    2022-02-16 08:49:22
  • asp之家 软件编程 m.aspxhome.com