Forms.Timer、Timers.Timer、Threading.Timer的研究
.NET Framework里面提供了三种Timer
System.Windows.Forms.Timer
System.Timers.Timer
System.Threading.Timer
一、System.Windows.Forms.Timer
1、基于Windows消息循环,用事件方式触发,在界面线程执行;是使用得比较多的Timer,Timer Start之后定时(按设定的Interval)调用挂接在Tick事件上的EvnetHandler。在这种Timer的EventHandler中可 以直接获取和修改UI元素而不会出现问题--因为这种Timer实际上就是在UI线程自身上进行调用的。
2、它是一个基于Form的计时器
3、创建之后,你可以使用Interval设置Tick之间的跨度,用委托(delegate)hook Tick事件
4、调用Start和Stop方法,开始和停止
5、完全基于UI线程,因此部分UI相关的操作会在这个计时器内进行
6、长时间的UI操作可能导致部分Tick丢失
例如

public partial class Form1 : Form

{
public Form1()
{
InitializeComponent();
}

int num = 0;

private void Form_Timer_Tick(object sender, EventArgs e)
{
label1.Text = (++num).ToString();
Thread.Sleep(3000);
}

private void button1_Click(object sender, EventArgs e)
{
Form_Timer.Start();
}

private void button2_Click(object sender, EventArgs e)
{
Form_Timer.Stop();
}
}

实例解析
1、上面这个是一个很简单的功能,在Form窗体上拖了一个System.Windows.Forms.Timer控件名字为Form_Timer,在属性窗中把Enable属性设置为Ture,Interval是定时器的间隔时间。双击这个控件就可以看到 Form_Timer_Tick方法。在这个方法中,我们让她不停的加一个数字并显示在窗体上,2个按钮提供了对计时器的控制功能。
2、执行的时候你去点击其他窗体在回来,你会发现我们的窗体失去响应了。因为我们这里使用Thread.Sleep(3000);让当前线程挂起,而UI失去相应,说明了这里执行时候采用的是单线程。也就是执行定时器的线程就是UI线程。
3、Timer 用于以用户定义的事件间隔触发事件。Windows 计时器是为单线程环境设计的,其中,UI 线程用于执行处理。它要求用户代码有一个可用的 UI 消息泵,而且总是在同一个线程中操作,或者将调用封送到另一个线程。
4、在Timer内部定义的了一个Tick事件,我们前面双击这个控件时实际是增加了一行代码
this.Form_Timer.Tick += new System.EventHandler(this.Form_Timer_Tick);
然后Windows将这个定时器与调用线程关联(UI线程)。当定时器触发时,Windows把一个定时器消息插入到线程消息队列中。调用线程执行一个消息泵提取消息,然后发送到回调方法中(这里的Form_Timer_Tick方法)。而这些都是单线程进行了,所以在执行回调方法时UI会假死。所以使用这个控件不宜执行计算受限或IO受限的代码,因为这样容易导致界面假死,而应该使用多线程调用的Timer。另外要注意的是这个控件时间精度不高,精度限定为 55 毫秒。
二、System.Timers.Timer
1. 用的不是Tick事件,而是Elapsed事件
2. 和System.Windows.Forms.Timer一样,用Start和Stop方法
3. AutoReset属性决定计时器是不是要发起一次事件然后停止,还是进入开始/等待的循环。System.Windows.Forms.Timer没有这个属性
4. 设置对于UI控件的同步对象(synchronizing object),对控件的UI线程发起事件
例如

public partial class Form1 : Form

{
public Form1()
{
InitializeComponent();
}

int num = 0;
DateTime time1 = new DateTime();
DateTime time2 = new DateTime();
//定义Timer
System.Timers.Timer Timers_Timer = new System.Timers.Timer();

private void button1_Click(object sender, EventArgs e)
{
//手动设置Timer,开始执行
Timers_Timer.Interval = 20;
Timers_Timer.Enabled = true;
Timers_Timer.Elapsed += new System.Timers.ElapsedEventHandler(Timers_Timer_Elapsed);
time1 = DateTime.Now;
}

void Timers_Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
label1.Text = Convert.ToString((++num)); //显示到lable
Thread.Sleep(3000);
}

private void button2_Click(object sender, EventArgs e)
{
//停止执行
Timers_Timer.Enabled = false;
time2 = DateTime.Now;
MessageBox.Show(Convert.ToString(time2-time1));
}
}

三、System.Threading.Timer

public partial class Form1 : Form

{
public Form1()
{
InitializeComponent();
}

int num = 0;
DateTime time1 = new DateTime();
DateTime time2 = new DateTime();
System.Threading.Timer Thread_Time;

private void button1_Click(object sender, EventArgs e)
{
//启动
Thread_Time = new System.Threading.Timer(Thread_Timer_Method,null,0,20);
time1 = DateTime.Now;

}

void Thread_Timer_Method(object o)
{
label1.Text = Convert.ToString((++num));
System.Threading.Thread.Sleep(3000);
}

private void button2_Click(object sender, EventArgs e)
{
//停止
Thread_Time.Dispose();
time2 = DateTime.Now;
MessageBox.Show(Convert.ToString(time2-time1));
}
}

实例解析
1、用Threading.Timer时的方法,和前面就不太相同了,所以的参数全部在构造函数中进行了设置,而且可以设置启动时间。而且没有提供start和stop方法来控制计时器。而且是以一种回调方法的方式实现,而不是通过事件来实现的。他们之间还是有区别的。
2、我们只有销毁掉对象来停止他。当你运行时,你会发现他和前面的Timers.Timer一样,是多线程的,主要表现在不会假死,调试运行报错。但跟让你奇怪的是,我们的代码竟然无法让她停止下来。调用了Dispose方法没有用。问题在那?然后有进行了测试,修改了间隔时间为100,200,500,1000,3000,4000。这几种情况。发现当间隔为500ms以上是基本马上就停止了。而间隔时间相对执行时间越短,继续执行的时间越长。这应该是在间隔时间小于执行时间时多个线程运行造成的。因为所有的线程不是同时停止的。间隔越短,线程越多,所以执行次数越多。
3、System.Threading.Timer 是一个简单的轻量计时器,它使用回调方法并由线程池线程提供服务。不建议将其用于 Windows 窗体,因为其回调不在用户界面线程上进行。
Forms.Timer、Timers.Timer、Threading.Timer的研究的更多相关文章
- System.Windows.Forms.Timer、System.Timers.Timer、System.Threading.Timer的 区别和用法
System.Windows.Forms.Timer执行的时候,如果你在过程中间加一个sleep整个的界面就死掉了,但是另外两个没有这个情况,System.Timers.Timer.System.Th ...
- System.Windows.Forms.Timer、System.Timers.Timer、System.Threading.Timer的差别和分别什么时候用
System.Windows.Forms.Timer.System.Timers.Timer.System.Threading.Timer的 区别和用法http://space.itpub.net/1 ...
- C# 计时器用法(DispatcherTimer、System.Timers.Timer、System.Threading.Timer)
首先,我觉得三种计时器最大的区别是:DispatcherTimer触发的内容会直接转到主线程去执行(耗时操作会卡住主线程),另外两个则是在副线程执行,如果需要修改界面,则需要手动转到主线程. Disp ...
- 定时器:Timer:System.Threading.Timer类(转)
最近的一个项目有一些地方需要用到定时功能,在设计过程中,突然发现.net的Timer类居然还有很多我以前没有用过的功能,这里就跟大家分享一下 注:这里的Timer类特指System.Threading ...
- .NET中System.Diagnostics.Stopwatch、System.Timers.Timer、System.Threading.Timer 的区别
1.System.Diagnostics.Stopwatch Stopwatch 实例可以测量一个时间间隔的运行时间,也可以测量多个时间间隔的总运行时间. 在典型的 Stopwatch 方案中,先调用 ...
- C# System.Threading.Timer 使用方法
public class TimerHelper { System.Threading.Timer timer; public TaskSendMMS tasksendmms { get; set; ...
- System.Threading.Timer的使用技巧
转自:http://www.360doc.com/content/11/0812/11/1039473_139824496.shtml# System.Threading.Timer timer = ...
- 当时钟事件声明为过程变量 让system.threading.timer时钟失效
这个项目的小模块就是画label 控件到tablepayoutpanel表单 之中, 中间用到了时钟,事件(带返回值的),哈希表 .由于时钟定义在 form1的启动构造函数中导致了form1,启动完毕 ...
- C# System.Threading.Timer的使用
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
随机推荐
- Codeforces Round #302 (Div. 1) D - Road Improvement 树形dp
D - Road Improvemen 思路:0没有逆元!!!! 不能直接除,要求前缀积和后缀积!!! #include<bits/stdc++.h> #define LL long lo ...
- d2i_xxx出错
在生成DER编码是X509_ALGOR类型没有赋值导致,要先new,然后赋值. req_st->req.appKeyReq->appKeyType = X509_ALGOR_new(); ...
- 专业的抢票软件 12306bypass
专业的抢票软件 https://www.12306bypass.com/
- cocos2dx各个版本下载地址
https://code.google.com/archive/p/cocos2d-x/downloads?page=1 各种工具包括 NDK 8 https://github.com/fusijie ...
- Django+Nginx+uwsgi搭建自己的博客(八)
在这篇博客中,我们开始为我们的博客开发Blogs App和Users App相关的管理功能,以便每个用户都能管理自己的博客以及评论.目前,Users App的管理功能相对简单,主要功能为查看用户资料以 ...
- 如何对富文本编辑器(FCK Html Editor)的工具栏进行扩展?
我们在项目开发过程中,会经常使用到富文本编辑器.GeneXus内置的富文本编辑器FCK Html Editor使用起来非常方便,只要将页面变量的控件类型(Control Type)选择为FCK Htm ...
- nyoj 269 VF 动规
VF 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 Vasya is the beginning mathematician. He decided to make a ...
- BZOJ1087【状压DP】
题目链接[http://www.lydsy.com/JudgeOnline/problem.php?id=1087] 题意:在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击 ...
- [BOI2004]Sequence
题面描述 给定整数数组$a_1,a_2,a_3...a_n$,求递增数组$b_1,b_2,b_3...b_n$ 使得$|a_1 - b_1| + |a_2 - b_2| + ... + |a_n - ...
- [HDU5965]扫雷
[HDU5965]扫雷 题目大意: 一个\(3\times n(n\le10000)\)的扫雷,第\(2\)排没有雷.告诉你第\(2\)排上的数,问有几种埋雷的方案? 思路: 动态规划. 将\(1,3 ...