C#执行定时计算限制操作(计时器)
来源:互联网 发布:手机校音器软件 编辑:程序博客网 时间:2024/06/15 10:24
c#执行定时计算限制操作(计时器)
在.Net Framework Class Library(FCL)中,System.Threading命名空间下定义了一个Timer类,这就是常用的一个计时器。实际上FCL总共提供了如下几种计时器:
1、System.Threading.Timer
在实际的开发中,这个类出现和使用频率非常高,下面就重点谈谈它的一些基础概念和应用实例。
(1)、常用的构造器
public
Timer(TimerCallback callback,
object
state,
int
dueTime,
int
period);
public
Timer(TimerCallback callback,
object
state,
long
dueTime,
long
period);
public
Timer(TimerCallback callback,
object
state, TimeSpan dueTime, TimeSpan period);
public
Timer(TimerCallback callback,
object
state,
uint
dueTime,
uint
period);
参数说明:
a、callback:望文生意,肯定表示一个回调,它是标识希望由一个线程池线程回调的方法。当然它的类型必须和System.Threading.TimerCallback委托类型匹配,如下所示:
public
delegate
void
TimerCallback(
object
state);
b、state:每次调用回调方法,向回调方法传递的状态数据,如没有,可以为null;
c、dueTime:在首次调用回调方法之前要等待多少毫秒。如希望立刻调用回调方法,该参数指定为0即可。
d、period:指定了以后每次调用回调方法之前要等待多少毫秒(理解成下一次和本次调用的时间间隔即可)。如果为该参数传递Timeout.Infinite(或者直接写-1),线程池线程只调用回调方法一次(那也就没有必要用计时器了)。
(2)、基本工作原理
在内部(原文应该指CLR内),线程池为所有Timer对象只使用了一个线程。这个线程知道下一个Timer对象在什么时候到期(计时器还有多久触发)。下一个Timer对象到期时,线程就会唤醒,在内部调用ThreadPool的QueueUserWorkItem,将一个工作项添加到线程池的队列中,使你的回调方法得到调用。
注意:如果回调方法的执行时间很长,计时器可能在上个回调还没有完成的时候再次触发(对于执行时间很长的任务,实际开发中通常不使用线程池,而是直接使用new一个Thread)。这可能会造成多个线程池线程同时调用你的方法(方法的重叠覆盖?)。为了解决这个问题,Jeffrey Richter建议我们这样使用Timer:
a、为period指定Timeout.Infinite。这样,计时器就只触发一次;
b、在回调方法中,调用Timer的Change方法来指定一个新的dueTime,并再次为period指定Timeout.Infinite。Change方法的几个重载版本:
public
bool
Change(
int
dueTime,
int
period);
public
bool
Change(
long
dueTime,
long
period);
public
bool
Change(TimeSpan dueTime, TimeSpan period);
public
bool
Change(
uint
dueTime,
uint
period);
Timer还有一个Dispose方法,允许完全取消计时器。
(3)、示例代码
internal
static
class
TimerDemo
{
private
static
Timer s_timer;
public
static
void
Main()
{
Console.WriteLine(
"Main thread: starting a timer"
);
using
(s_timer =
new
Timer(ComputeBoundOp, 5, 0, Timeout.Infinite))
{
Console.WriteLine(
"Main thread: Doing other work here..."
);
Thread.Sleep(10000);
// Simulating other work (10 seconds)
}
// Calls Dispose to cancel the timer now
Console.Read();
}
// This method's signature must match the TimerCallback delegate
private
static
void
ComputeBoundOp(Object state)
{
// This method is executed by a thread pool thread
Console.WriteLine(
"In ComputeBoundOp: state={0}"
, state);
Thread.Sleep(1000);
// Simulates other work (1 second)
// Have the Timer call this method again in 2 seconds
s_timer.Change(2000, Timeout.Infinite);
// When this method returns, the thread goes back
// to the pool and waits for another work item
}
}
这个示例是<<CLR via C#>>中的源码,虽然简单,却贯穿实现了创建Timer,Timer定时工作到Timer的销毁一整个生命周期。using语句我们可以使用try finally替换,在finally语句块中显式调用Dispose方法。注意,程序中输出了四次“In ComputeBoundOp: state=5”,您不妨多想一想为什么只有4次。而如果我们把Main方法的这一行:
Thread.Sleep(10000);
// Simulating other work (10 seconds)
注释掉,程序有时候会抛出“程序无法访问已释放对象”的异常,而且每次输出的结果可能还不一样。之所以这么说,是因为using语句不能保证静态Timer立刻被垃圾回收器回收。您不妨自己动手一试。
2、System.Timers.Timer
这个类据说基本上就是System.Threading.Timer的包装过的“整过容的副产品”。当计时器到期触发时,会导致CLR将事件放到线程池的队列中。该类派生自System.ComponentModel的Component类,允许VS将计时器对象放到设计平面上,并公开了它的属性和事件(不就是一个控件吗,难道?)。
3、System.Windows.Forms.Timer
构造一个该类的实例,相当于告诉Windows将一个计时器和调用线程关联。当这个计时器被触发时,Windows将一条及时消息注入线程的消息队列。线程必须执行一个消息泵来提取这些消息,并把它们派遣给想要的回调方法。注意,所有这些工作都只由一个线程完成——设置计时器的线程保证就是执行回调方法的线程。这还意味着你的计时器方法不会由多个线程并发执行。
4、System.Windows.Threading.DispatcherTimer
这个类是System.Windows.Forms的Timer在WPF和SilverLight应用程序中的等价物。通俗地说,这个类也就是System.Windows.Forms的Timer在WPF和SilverLight下的一个马甲。擅于改头换面新瓶装旧酒在MS的技术领域中也不是一天两天的事情了。
在Jeffrey Richter 的<<CLR via C#>>中关于计时器有很精练的说明,其中他说“事实上,我个人从来不用System.Timers.Timer类,建议你也不要用它”,他的这种态度蛮好玩的。反正对于这个类我倒是用过不少,而且一直没出过什么差错,就算是”山寨“或者”马甲“也不是从来都是一无是处。
参考:
Jeffrey Richter <<CLR via C#>>
http://msdn.microsoft.com/zh-cn/library/system.threading.timer.aspx
原文地址:
http://www.cnblogs.com/jeffwongishandsome/archive/2010/11/15/1877837.html
- C#执行定时计算限制操作(计时器)
- C#定时执行一个操作
- Android 计时器Timer用法 (定时执行任务)
- 使用C#系统服务定时执行操作
- C# 使用APM执行受I/O限制的异步操作(转)
- APM和计算限制的操作--CLR via c#
- C# 定时执行函数(winForm)
- C# 定时执行函数(winForm)
- C#定时执行某个程序(转)
- C# 定时执行任务
- c#定时执行源代码
- C# 定时执行任务
- C# 定时执行程序
- C# 定时执行1
- C#定时执行程序
- C#定时执行程序
- PHP 定时执行操作
- C#定时 器 定时执行任务 线程
- pat1054The Dominant Color (20)
- android----动画Animation
- nodejs+phantomjs+casperjs
- 软件开发的文档与审查
- GPS 射频调试总结
- C#执行定时计算限制操作(计时器)
- 项目稳定回报论证—大数据进入价值变现的2.0时代
- [php] thinkphp基于Http类 下载文件
- Java语言基础(三)
- 死锁、进程通信以及进程线程的区别
- C++中的函数指针
- sigaction,SA_RESTART
- android 获取控件高度
- Linux设置默认启动命令行,而不是图形界面