来源于:http://blog.sina.com.cn/s/blog_62c501440100fog1.html

System.Threading.Timer 是一个非常常用的定时器类,关于这个类的使用,我们需要注意以下几点:
   1.System.Threading.Timer 的任何一个实例,实际上是通过使用win32底层(非.NET Thread Pool中的线程)来进行调度的。
   2.当到达调度时刻时,System.Threading.Timer 将异步调用由TimerCallback参数指定的回调方法。也就是说TimerCallback所指向的方法将在.NET Thread Pool中的工作者线程中执行。
   3.当.NET Thread Pool中没有空闲线程时,对TimerCallback所指向的方法的调用将被ThreadPool排队。而这并不会影响System.Threading.Timer的正常调度过程--当到达调度时间点,System.Threading.Timer仍然触发异步调用。
   顺便补充一下,经过我的测试发现,ThreadPool中默认的最大工作线程数是25/CPU,最大完成端口线程数是1000。(双核最大工作线程就是25*2/CPU)

System.Threading.Timer 是一个使用回调方法的计时器,而且由线程池线程服务,简单且对资源要求不高。
只要在使用 Timer,就必须保留对它的引用。对于任何托管对象,如果没有对 Timer 的引用,计时器会被垃圾回收。即使 Timer 仍处在活动状态,也会被回收。当不再需要计时器时,请使用 Dispose 方法释放计时器持有的资源。
 
使用 TimerCallback 委托指定希望 Timer 执行的方法。计时器委托在构造计时器时指定,并且不能更改。此方法不在创建计时器的线程中执行,而是在系统提供的线程池线程中执行。
 
创建计时器时,可以指定在第一次执行方法之前等待的时间量(截止时间)以及此后的执行期间等待的时间量(时间周期)。可以使用 Change 方法更改这些值或禁用计时器。
Demo application:
应用场景:在windows form程序自动执行某项工作后,希望其windows form能够自动关闭。
代码设计:(1)首先声明Timer变量:
private System.Threading.Timer timerClose;
 
(2)在上述自动执行代码后面添加如下Timer实例化代码:
// Create a timer thread and start it
timerClose = new System.Threading.Timer(new TimerCallback(timerCall), this, 5000, 0);
 
Timer构造函数参数说明:
Callback:一个 TimerCallback 委托,表示要执行的方法。
State:一个包含回调方法要使用的信息的对象,或者为空引用(Visual Basic 中为 Nothing)。
dueTime:调用 callback 之前延迟的时间量(以毫秒为单位)。指定 Timeout.Infinite 以防止计时器开始计时。指定零 (0) 以立即启动计时器。
Period:调用 callback 的时间间隔(以毫秒为单位)。指定 Timeout.Infinite 可以禁用定期终止。
 
(3)定义TimerCallback委托要执行的方法:
private void timerCall(object obj)
{
      timerClose.Dispose();
      this.Close();
}
 
当然,除了使用上述System.Threading.Timer类的TimerCallback 委托机制外,应该还有很多其他的办法。另外,这里只是demo了TimerCallback委托的简单应用。
-------------------------------------------------------------------------------------------------------------------------------------------------------
转载地址:http://www.jb51.net/article/56725.htm

本文实例讲述了C#中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 窗体,因为其回调不在用户界面线程上进行。

希望本文所述对大家的C#程序设计有所帮助。

c# 中定时器的用法的更多相关文章

  1. javascript中window与document对象、setInterval与setTimeout定时器的用法与区别

    一.写在前面 本人前端菜鸟一枚,学习前端不久,学习过程中有很多概念.定义在使用时容易混淆,在此给向我一样刚踏入前端之门的童鞋们归纳一下.今天给大家分享一下js中window与document对象.se ...

  2. mysql中event的用法详解

    一.基本概念mysql5.1版本开始引进event概念.event既“时间触发器”,与triggers的事件触发不同,event类似与linux crontab计划任务,用于时间触发.通过单独或调用存 ...

  3. JavaScript中this的用法 及 如何改变this的指向

    要懂得JavaScript中this的用法,首先需要知道,JavaScript中的作用域相关知识. var fun = function(){ var flag = 1; console.log(fl ...

  4. Vuex中mapState的用法

    Vuex中mapState的用法   今天使用Vuex的时候遇到一个坑,也可以说是自己的无知吧,折腾了好久,终于发现自己代码的错误了.真是天雷滚滚~~~~~~ index.js import Vue ...

  5. JS定时器的用法及示例

    JS定时器的用法及示例 目录 js 定时器的四个方法 示例一 示例二 示例三 js 定时器的四个方法 setInterval() :按照指定的周期(以毫秒计)来调用函数或计算表达式.方法会不停地调用函 ...

  6. Java中定时器Timer致命缺点(附学习方法)

    简介 这篇文章我一直在纠结到底要不要写,不想写一来因为定时器用法比较简单,二来是面试中也不常问.后来还是决定写了主要是想把自己分析问题思路分享给大家,让大家在学习过程中能够参考,学习态度我相信大部分人 ...

  7. [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法

    一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...

  8. C#中string.format用法详解

    C#中string.format用法详解 本文实例总结了C#中string.format用法.分享给大家供大家参考.具体分析如下: String.Format 方法的几种定义: String.Form ...

  9. SQL中distinct的用法

    SQL中distinct的用法   1.作用于单列 2.作用于多列 3.COUNT统计 4.distinct必须放在开头 5.其他 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出 ...

随机推荐

  1. FPGA边缘检测

    沿检测技术在项目应用中, 非常低广泛. 如要有效捕获信号跳变沿, 边沿 检测技术的应用是必不可少的.大致如下: (1) 将时钟边沿使能转换为边沿检测使能,使时钟同步化. (2) 捕获信号的突变( UA ...

  2. 【knowledgebase】如何知道partition数

    对于调优和排错来说,查看一个RDD有多少个partition是非常有用的.常用的查看方法有如下几种: 1.通过SparkUI查看Task执行的partition数 当一个stage执行时,能通过Spa ...

  3. QTP实现功能测试的时候,当新版本的页面都改变了,应该如何解决

    去更改对象仓库的属性和更改对象仓库.

  4. C++标准转换运算符

    C++类型转换在实际编程中会经常使用,其实,本质上对象的类型用来解释(interpret)对象.因为,每个对象都占据一块内存空间,这块内存空间存放了一段二进制数据.通过标记该对象的类型,告诉如何看待这 ...

  5. Fliwer:监控植物状态 实现远程浇水

    Fliwer是一款针对植物而研发出来的设备,可以监控土壤水分.光照.温度.空气湿度和肥料是否充足这些指标.结合云端的植物数据和天气预报,它能够自动决定什么时候给植物浇水,甚至提醒你什么时候应该施肥.修 ...

  6. Ubuntu14.04通过pyenv配置多python

    参考链接: https://github.com/yyuu/pyenv-virtualenv https://github.com/yyuu/pyenv http://seisman.info/pyt ...

  7. 温习SQL server

    做了好几年的管理工作,技术上有些退步,现在又一一捡起来啦, 以下最近几天看到的好文章, SQL Server约束 http://blog.csdn.net/qq61394323/article/det ...

  8. 共用字体-UI界面编辑器(SkinStudio)教程

    添加一个Label控件,设置好字体属性 再添加一个Label控件,字体属性还是默认的 只需要将字体属性的Name字段名称改为需要使用的字体属性的Name字段名称即可(如Label1使用的字体)

  9. c++学习笔记——智能指针

    智能指针是为了便于管理动态内存,能够自动管理释放所指向的对象. 智能指针共有三种:1.shared_ptr允许多个指针指向同一个对象:2.unique_ptr独占所指向的对象:3.weak_ptr是一 ...

  10. C#连接数据库的四种方法

    在进行以下连接数据库之前,请先在本地安装好Oracle Client,同时本次测试System.Data的版本为:2.0.0.0. 在安装Oracle Client上请注意,如果OS是3-BIT请安装 ...