在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. 文件 IO

    io分类 在文件IO 中是通过文件描述符操作文件的,实际上是一个非负整数 头文件   #include <sys/types.h>   #include <sys/stat.h> ...

  2. Linux CentOS-7.0上安装Tomcat7

    Linux CentOS-7.0上安装Tomcat7   安装说明 安装环境:CentOS-7.0.1406安装方式:源码安装 软件:apache-tomcat-7.0.29.tar.gz 下载地址: ...

  3. sublime快捷键汇总

    Sublime Text 3 快捷键精华版 Ctrl+Shift+P:打开命令面板Ctrl+P:搜索项目中的文件Ctrl+G:跳转到第几行Ctrl+W:关闭当前打开文件Ctrl+Shift+W:关闭所 ...

  4. CGLIB 详解

    依赖 <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> ...

  5. R语言 环境设置

    尝试在线环境 你真的不需要设置自己的环境来开始学习R编程语言. 原因很简单,我们已经在线设置了R编程环境,以便您可以在进行理论工作的同时在线编译和执行所有可用的示例. 这给你对你正在阅读的信心,并用不 ...

  6. 56 Marvin: 一个支持GPU加速、且不依赖其他库(除cuda和cudnn)的轻量化多维深度学习(deep learning)框架介绍

    0 引言 Marvin是普林斯顿视觉实验室(PrincetonVision)于2015年提出的轻量化GPU加速的多维深度学习网络框架.该框架采用纯c/c++编写,除了cuda和cudnn以外,不依赖其 ...

  7. NOIp2018集训test-9-17(pm)

    T1记忆(memory) 我大概是只记忆只有七秒的金鱼吧.看了下以前的代码发现真的很简单,但是考场上只打了个暴力,虽然骗了88pt.就是枚举选的是哪个串,然后vis[i]表示选了i这些位能不能猜出它, ...

  8. How to SSH Into Your iPhone

    First, I will explain what SSH is and why we do it. SSH (Secure Shell) allows you to exchange data b ...

  9. The packaging for this project did not assign a file to the build artifact

    当进行mvn install时,遇到以下错误 The packaging for this project did not assign a file to the build artifact 在网 ...

  10. 基于Netty的RPC架构学习笔记(二):netty服务器

    文章目录 简介 Netty服务端Hello World案例 举个