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

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。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#中的三种定时计时器Timer用法介绍

    在.NET中有三种计时器: 1.System.Windows.Forms命名空间下的Timer控件,它直接继承自Componet.Timer控件只有绑定了Tick事件和设置Enabled=True后才会自动计时,停止计时可以用Stop()方法控制,通过Stop()停止之后,如果想重新计时,可以用Start()方法来启动计时器.Timer控件和它所在的Form属于同一个线程: 2.System.Timers命名空间下的Timer类.System.Timers.Timer类:定义一个System.T

  • c# 实现计时器功能

    场景 在低液位预警弹窗点击确定后需要实现一个计时器,比如在五分钟后再执行监控. 实现思路是使用Timer然后每秒执行一个方法,在方法中对秒数进行减1操作,等倒计时结束后执行相应的操作. 实现 但是Timer有三个 1.定义在System.Windows.Forms里   2.定义在System.Threading.Timer类里   3.定义在System.Timers.Timer类里 一开始使用的是System.Windows.Forms里面的 System.Windows.Forms.Tim

  • C#线程倒计时器源码分享

    本文实例为大家分享了C#线程倒计时器源码,供大家参考,具体内容如下 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Windows.Forms; namespace ListZZBG { class TimeHeleper { Thread thread; private TimeSpan time;

  • C#中各种计时器用法小结

    本文实例总结了C#中各种计时器用法.分享给大家供大家参考,具体如下: 1.使用 Stopwatch 类 (System.Diagnostics.Stopwatch) Stopwatch 实例可以测量一个时间间隔的运行时间,也可以测量多个时间间隔的总运行时间.在典型的 Stopwatch 方案中,先调用 Start 方法,然后调用 Stop 方法,最后使用 Elapsed 属性检查运行时间. Stopwatch 实例或者在运行,或者已停止:使用 IsRunning 可以确定 Stopwatch 的

  • c# 区分几种定时器(timer)

    1.前言 不知道你是否对.NET里面的定时器产生过一些疑问,以下是武小栈个人的一些总结. 2.官方介绍 在.NET的框架之内定时器有四种,先看一下微软官方对他们各自特点介绍: System.Timers.Timer,它将触发事件,并定期在一个或多个事件接收器中执行代码. 类旨在用作多线程环境中基于服务器的组件或服务组件;它没有用户界面,在运行时不可见. System.Threading.Timer,它按固定的时间间隔对线程池线程执行单个回调方法. 回调方法是在实例化计时器时定义的,无法更改. 与

  • 详解C#中的定时器Timer类及其垃圾回收机制

    关于C# Timer类  在C#里关于定时器类就有3个 C# Timer使用的方法1.定义在System.Windows.Forms里 C# Timer使用的方法2.定义在System.Threading.Timer类里  " C# Timer使用的方法3.定义在System.Timers.Timer类里 下面我们来具体看看这3种C# Timer用法的解释: (1)System.Windows.Forms.Timer 应用于WinForm中的,它是通过Windows消息机制实现的,类似于VB或D

  • c#各种Timer类的区别与用法介绍

    System.Threading.Timer 是一个简单的轻量计时器,它使用回调方法并由线程池线程提供服务.在必须更新用户界面的情况下,建议不要使用该计时器,因为它的回调不在用户界面线程上发生.在此类情况下,System.Windows.Threading.DispatcherTimer 是更好的选择,因为其事件是在用户界面线程上引发的. 多线程计时器1:System.Threading.Timer2:System.Timers.Timer 特殊目的的单线程计时器:1:System.Window

  • C#中timer定时器用法实例

    本文实例讲述了C#中timer定时器用法.分享给大家供大家参考.具体如下: 下面的代码通过Timer定时器每隔1000毫秒(1秒)触发一次事件 using System; using System.Timers; class TestTimer { public static void Main () { Timer timer = new Timer(); timer.Elapsed + = new ElapsedEventHandler(DisplayTimeEvent); timer.In

  • C#计时器的三种实现方法

    在.NET中有三种计时器: 一. System.Windows.Forms命名空间下的Timer控件,和所在的Form属于同一个线程.Timer控件只有绑定了Tick事件和设置Enabled属性为True之后才会自动计时,Stop()方法,Start()方法启动计时器重新计时: MyTimer.Enabled = true;  //启动计时器 MyTimer.Interval = 1000; //设置计时器时间间隔,单位为ms MyTimer.Stop(); //停止计时 MyTimer.Sta

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

    1.System.Threading.Timer 线程计时器 1.最底层.轻量级的计时器.基于线程池实现的,工作在辅助线程. 2.它并不是内在线程安全的,并且使用起来比其他计时器更麻烦.此计时器通常不适合 Windows 窗体环境. 构造函数:public Timer(TimerCallback callback, object state, int dueTime, int period); string state="."; //state参数可以传入想在callback委托中处理

  • 浅谈Java中的四种引用方式的区别

    强引用.软引用.弱引用.虚引用的概念 强引用(StrongReference) 强引用就是指在程序代码之中普遍存在的,比如下面这段代码中的object和str都是强引用: Object object = new Object(); String str = "hello"; 只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象. 比如下面这段代码: public class Main { publi

  • Android中AlertDialog四种对话框的最科学编写用法(实例代码)

    首先我们上图: xml的代码如下,用于编写按钮: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match

  • 解析C++中四种强制类型转换的区别详解

    C++的四种强制类型转换,所以C++不是类型安全的.分别为:static_cast , dynamic_cast , const_cast , reinterpret_cast为什么使用C风格的强制转换可以把想要的任何东西转换成合乎心意的类型.那为什么还需要一个新的C++类型的强制转换呢?新类型的强制转换可以提供更好的控制强制转换过程,允许控制各种不同种类的强制转换.C++中风格是static_cast<type>(content).C++风格的强制转换其他的好处是,它们能更清晰的表明它们要干

  • 详解Java的四种引用方式及其区别

    java内存管理分为内存分配和内存回收,都不需要程序员负责,垃圾回收的机制主要是看对象是否有引用指向该对象. java对象的引用包括 强引用,软引用,弱引用,虚引用 Java中提供这四种引用类型主要有两个目的: 第一是可以让程序员通过代码的方式决定某些对象的生命周期: 第二是有利于JVM进行垃圾回收. 下面来阐述一下这四种类型引用的概念: 1.强引用 是指创建一个对象并把这个对象赋给一个引用变量. 比如: Object object =new Object(); String str ="hel

  • Python中几种属性访问的区别与用法详解

    起步 在Python中,对于一个对象的属性访问,我们一般采用的是点(.)属性运算符进行操作.例如,有一个类实例对象foo,它有一个name属性,那便可以使用foo.name对此属性进行访问.一般而言,点(.)属性运算符比较直观,也是我们经常碰到的一种属性访问方式. python的提供一系列和属性访问有关的特殊方法: __get__ , __getattr__ , __getattribute__ , __getitem__ .本文阐述它们的区别和用法. 属性的访问机制 一般情况下,属性访问的默认

  • TCP 四种定时器(重传定时器,坚持计时器,保活定时器,时间等待计时器)

    TCP 四种定时器 重传定时器 主要为了防止报文丢失或者阻塞.当A向B发送报文时,就会启动重传定时器,若在定时器到达之后,仍没有收到B的确认报文,则A会重新发送上次发送的报文.同时,令重传定时器复位.继续计时. 坚持计时器 此计时器针对下面场景: 当B向A发送了0窗口报文,B此时已经没有空间接受A发送的数据了,通知A停止发送.A在收到后即停止发送,等待一段时间后,B有了一些空间,可以继续接收了.此时再向A发送非0窗口报文.如果此非0窗口报文在网络中阻塞或者丢失了,那么A将永远以为B没有空间接收数

  • Java Rabbitmq中四种集群架构的区别详解

    目录 主备模式 远程模式 镜像模式 多活模式 Federation插件 总结 Rabbitmq 四种集群架构 1. 主备模式 2. 远程模式3. 镜像模式  4. 多活模式 主备模式 主备模式: warren 兔子窝 一个主.一个备方案 主节点如果挂了 从节点提供服务 和Activemq 利用zk 做主/备一样 主备模式 ----------------------->HaProxy 配置 listen rabbitmq_cluster bind 0.0.0.0:5682 # 配置tcp 模式

  • Golang定时器的2种实现方法与区别

    不得不说,golang的sdk做了太多的东西,定时器在golang里实现起来非常的简单 两种方式 NewTicker() NewTimer() 代码如下 NewTicker() 方式 func foo() { fmt.Println("foo() start.") time.Sleep(time.Second * 3) fmt.Println("foo() end.") } func TestTicker(t *testing.T) { ticker := time

随机推荐