在Framework中存在着4种定时器:其中分为两类,

多线程计时器

1:System.Threading.Timer

2:System.Timers.Timer

特殊目的的单线程计时器:

1:System.Windows.Forms.Timer(Windows Forms Timer)

2:System.Windows.Threading.DispatcherTimer(WPF timer);

多线程计时器比较强大,精确,而且可扩展性强;

单线程计时器比较安全,对于更新 Windows Forms controls或者WPF这种简单任务来说更方便。

System.Threading.Timer是最简单的多线程计时器。在下面的例子中,定时器在5秒后开始定时1秒的调用Tick方法。

public static void Main ()
{
//5秒后开始运行,接着每隔1秒的调用Tick方法
Timer tmr = new Timer(Tick, "tick...", 5000, 1000);
Console.ReadLine();
tmr.Dispose();
}
static void Tick(object data)
{
Console.WriteLine(data);
}

.net framework提供的另一个计时器System.Timers.Timer.简单的对System.Threading.Timer进行了包装。增加了下面几个特性。

  • 实现了Component,所以可以在设计器显示。
  • 代替Change方法的一个Interval属性
  • 代替callback委托的一个Elapsed事件
  • 启动和停止timer的Enabled属性,默认是false。
  • 为了避免Enabled造成混乱,提供了Start和Stop方法。
  • 是否在每次指定的间隔结束时引发Elapsed时间,还是仅间隔第一次结束后运行的AutoReset属性。
  • 在WPF或Windows Forms中安全的调用方法的SynchronizingObject对象。
public static void MainThread()
{
Timer tmr = new Timer();
tmr.Interval = 500;
tmr.Elapsed += new ElapsedEventHandler(tmr_Elapsed);
tmr.Start();
Console.ReadLine();
tmr.Stop();
Console.ReadLine();
tmr.Start();
Console.ReadLine();
tmr.Dispose();
}

static void tmr_Elapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Tick...");

  单线程计时器:

1:System.Windows.Forms.Timer(Windows Forms Timer)

2:System.Windows.Threading.DispatcherTimer(WPF timer);

单线程计时器是被设计成属于他们执行环境的计时器,如果你在一个Windows服务应用程序中使用Windows Forms的Timer,timer 事件并不会被触发,只有在对应的环境下才会被触发。

像System.Timers.Timer一样,他们也提供了相同的成员(Interval,Tick,Start,Stop),但是他们内部的工作原理不同,

WPF和Windows Forms的计时器使用消息循环机制来取代线程池产生消息的机制。

这意味着Tick事件总是在创建timer的那个线程上执行,同时也意味着如果上一个Tick消息还未被处理,即使时间超过了间隔时间,在消息循环中也只存在一个Tick消息。

下面是它们的优点:

  1. 你可以忘记线程安全。
  2. 一个Tick事件在前一个Tick事件被处理完毕前不会被触发。
  3. 你可以直接在Tick事件处理代码中更新控件,不需要调用Control.Invoke或Dispatcher.Invoke.

看下在Winform中使用单线程定时器的效果:

//基于Windows消息循环的单线程计时器
private System.Windows.Forms.Timer timer = new Timer() { };

public Form1()
{
InitializeComponent();

timer.Tick += new EventHandler(timer_Tick);
timer.Enabled = true;
}

void timer_Tick(object sender, EventArgs e)
{
//模拟的做一些耗时的操作
System.Threading.Thread.Sleep(2000);
}

如果运行上面的代码,会发现UI界面响应速度很慢,

原理上面已经介绍了:单线程计时器基于Windows消息循环,应用程序会同步的处理计时器的消息。

解决这个问题的方法是使用多线程计时器:只要修改代码使用多线程计时器即可:

//使用多线程计时器
private System.Timers.Timer timer = new System.Timers.Timer();

public Form1()
{
InitializeComponent();

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

void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//模拟的做一些耗时的操作
System.Threading.Thread.Sleep(2000);
}

上面的例子告诉我们单线程计时器的缺点:

除非Tick事件的处理代码执行的非常快,否则UI界面会变得响应很慢。

所以 WPF和Windows Forms的计时器都非常适合小任务,尤其是界面更新的任务。例如时钟和计数显示。否则,你需要一个多线程计时器

.net Framework 中的四种计时器的更多相关文章

  1. TCP四种计时器

    TCP共使用以下四种计时器,即重传计时器.坚持计时器.保活计时器和时间等待计时器 .这几个计时器的主要特点如下:      1.重传计时器      当TCP发送报文段时,就创建该特定报文段的重传计时 ...

  2. 对称加密和分组加密中的四种模式(ECB、CBC、CFB、OFB)

    一. AES对称加密: AES加密 分组 二. 分组密码的填充 分组密码的填充 e.g.: PKCS#5填充方式 三. 流密码:   四. 分组密码加密中的四种模式: 3.1 ECB模式 优点: 1. ...

  3. JAVA基础学习之throws和throw的区别、Java中的四种权限、多线程的使用等(2)

    1.throws和throw的区别 throws使用在函数外,是编译时的异常,throw使用在函数内,是运行时的异常 使用方法 public int method(int[] arr) throws ...

  4. Activity中的四种启动模式

    在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. An ...

  5. C++中的四种转型操作符

    在具体介绍C++中的四种转型操作符之前,我们先来说说旧式转型的缺点: ①它差点儿同意将不论什么类型转换为不论什么其它类型,这是十分拙劣的.假设每次转型都可以更精确地指明意图,则更好. ②旧式转型难以辨 ...

  6. JAVA中的四种引用以及ReferenceQueue和WeakHashMap的使用示例

    简介: 本文主要介绍JAVA中的四种引用: StrongReference(强引用).SoftReferenc(软引用).WeakReferenc(弱引用).PhantomReference(虚引用) ...

  7. C语言_了解一下C语言中的四种存储类别

    C语言是一门通用计算机编程语言,应用广泛.C语言的设计目标是提供一种能以简易的方式编译.处理低级存储器.产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言. C语言中的四种存储类别:auto ...

  8. Java中的四种引用

    引用定义 实际上,Java中存在四种引用,它们由强到弱依次是:强引用.软引用.弱引用.虚引用.下面我们简单介绍下这四种引用: 强引用(Strong Reference):通常我们通过new来创建一个新 ...

  9. JavaScript确定一个字符串是否包含在另一个字符串中的四种方法

    一.indexOf() 1.定义 indexOf()方法返回String对象第一次出现指定字符串的索引,若未找到指定值,返回-1.(数组同一个概念) 2.语法 str.indexOf(searchVa ...

随机推荐

  1. python代码自动补全

    牛逼了!Python代码补全利器,提高效率告别996! Python之禅 Python之禅 微信号 VTtalk 功能介绍 人生苦短,我用Python,这里是一名老程序员分享Python技术的地方,欢 ...

  2. JAVA jar命令(一)-jar打包class文件

    jar包本质上是将所有class文件.资源文件压缩打成一个包(也可以选择不压缩),可选择在jar包中生成META-INF/MANIFEST.MF文件,MANIFEST.MF是清单文件,里面可以记录主类 ...

  3. bzoj1004题解

    [题意分析] 给N个元素染色,可以在定置换群的作用下互相转化的染色方案算相同的,问本质不同的染色方案数. [解题思路] 引理:Burnside定理 设集合S=[1,n]∩N,记等价类数为L,给定S上的 ...

  4. NX二次开发-UFUN计时函数UF_begin_timer

    NX9+VS2012 #include <uf.h> #include <uf_modl.h> UF_initialize(); //计时开始 UF_timer_t Timer ...

  5. 2018-06-05(thinking in java)

    1:类只能有2种访问权限,一种是不写访问权限:默认包访问权限,另一种是public.且类只能有一个pubic 2:方法有4种访问权限,pubic(都可以访问),protexted(继承访问权限),pr ...

  6. Go语言中new()和 make()的区别详解

    概述 Go 语言中的 new 和 make 一直是新手比较容易混淆的东西,咋一看很相似.不过解释两者之间的不同也非常容易. new 的主要特性 首先 new 是内建函数,你可以从 http://gol ...

  7. CodeForces 1152F1 Neko Rules the Catniverse (Small Version)

    题目链接:http://codeforces.com/problemset/problem/1152/F1 题目大意 有 n 个星球,给定限制 m,从 x 星球走到 y 星球的条件是,$1 \leq ...

  8. i++ 和 ++i 的区别

    先说运算规则吧. i++ 是先赋值后自增:++i 是先自增后赋值. 以下是代码示例: int a=0; int b=0; int i=0; a=i++; System.out.println(&quo ...

  9. 《DSP using MATLAB》Problem 8.46

    下雨了,大风降温,一地树叶,终于进入冬季了 代码: %% ----------------------------------------------------------------------- ...

  10. adostoredproc用法 因为用的少每次还得看一下代码,记下来

    {1.关闭2.清除参数(固定的可省略)3.参数赋值4.打开(或执行)如果有感知控件的话 就会显示出结果} ADOStoredProc1.close; //关闭 ADOStoredProc1.param ...