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 ...
随机推荐
- Am335x u-boot 启动过程中的系统频率配置
Am335x的时钟结构分为:ADPLLS和ADPLLLJ 1.ADPLLS用来配置Core_CLK,Dispaly_clk,ARM系统CLK(mpu_clk),DDR PLLs_clk 2.ADPLL ...
- 关联的CURD
在保存的前面必须先建立好关联.但是默认情况下还是不会自动保存,如果保存会出错. Cascade all所有关联的所有持久化都是级联到另一个对象.保存这个对象的时候关联的对象自动保存. Cascade只 ...
- 打开tcp_tw_recycle引起的一个问题
今天普空说了一个问题就是如果设置了tcp_tw_recycle ,那么如果客户端是NAT出来的,那么就可能会出现连接被直接rst的情况.然后我google了下,在内核列表也有人说了这个问题 https ...
- SRPG Studio 教程(一) 创建游戏及引用素材
儿时玩红白机的时候,火纹和机器人大战这类战棋类的游戏就是博主的最爱,恰逢最近steam上上架了一款SRPG Studio用于制作火纹,趁这个机会学习一下,顺便记录下来. 秉承着一个程序猿的自我修养,以 ...
- 基础知识(09) -- Spring 概述
Spring概述-------------------------------------------------------------------------主要内容: 1.Spring是什么 2 ...
- Python,JAVA中子类的构造函数与父类构造函数的关系
Python: 子类不重载.覆盖父类的构造函数(子类不自己定义构造函数),则构造子类时会调用父类构造函数 若子类覆盖了父类的构造函数,则构造子类时不执行父类的构造函数,但仍继承了父类,如需调用父类构造 ...
- Ubuntu 16.04开启SFTP服务
说明:其实只要安装了SSH服务就已经具备了SFTP功能,这个用普通客户端无法连接,只能用支持SFTP协议的客户端才能连接. FileZilla作为FTP客户端,它也可以连接SFTP,SFTP的监听端口 ...
- springMvc的一些简介 和基于xml的handlerMapping基本流程
其它步骤就不在介绍了 在大多数情况,都会使用基于annotation的方式进行HandlerMapping处理,在这里基于对这个流程的了解,就采用了基于xml配置了一个HandlerMapping & ...
- 杭州有赞公司招聘 资深PHP开发工程师(平台架构方向)、技术专家
- Ext表格控件
表格控件其实也就是帮我们完成了数据的填充工作而已,具体的数据源.要显示的列,列的定制.数据源中的哪条数据显示在哪个列中等属性还是需要我们自己手动配置的,所以我们分下面几步来完成网格控件的数据绑定: 1 ...