System.Threading.Timer类的TimerCallback 委托
Written by: Rickie Lee
Nov. 19, 2004
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委托的简单应用。
Appendix about the article
在读一段关于Design Pattern的代码时,看到使用Timer类TimerCallback委托,随并记录下来。
Reference:
1, MSDN, System.Threading.Timer class
评论
谢谢
回复 引用 查看
1. 好像大材小用了。
2. 由线程池执行WinForm控件(包括Form)的方法非常危险!因为这些方法只能由创建该窗口控件的线程执行。
3. 由线程池线程服务,资源要求不高的说法是有问题的,因为 a)需要线程切换;b)需要创建windows核心对象。
总之,System.Threading.Timer改成System.Windows.Forms.Timer更加合适
回复 引用 查看
*
1. 好像大材小用了。
是的,这里只是提供一个简单的Demo演示一下而已。
Sorry,没有很明白你的意思,希望可以进一步阐述,谢谢。
*
根据Microsoft的文档:TimerCallback委托声明的回调方法,不在创建计时器的线程中执行(创建计时器的线程也就是创建该窗口控件的线程),而是在系统提供的线程池线程中执行。
*
如果根据上述特定的Demo程序而言,正如你说言,System.Windows.Forms.Timer可能更合适。
msolap, 谢谢你的回复。
回复 引用 查看
第3)点,英文原文应该是
System.Threading.Timer is a simple, lightweight timer that uses callback methods and is served by threadpool threads.
lightweigth并非指对资源要求低,只是相对于过去常用的CreateWaitableTimer(Win32 SDK)而言低一点。
其实从贵文中第二段:“当不再需要计时器时,请使用 Dispose 方法释放计时器持有的资源。” 就可以体会到它对资源的要求。:-)
回复 引用 查看
*
But why do you think it's very dangerous when doing it this way?
Thanks.
回复 引用 查看
回复 引用 查看
回复 引用 查看
回复 引用 查看
回复 引用
谢谢
System.Windows.Forms.Timer tmr2 = new System.Windows.Forms.Timer();
private void button3_Click(object sender, System.EventArgs e)
{
System.Threading.ThreadStart thds = new ThreadStart(label);
System.Threading.Thread thd = new Thread(thds);
thd.Start();
}
private void label()
{
tmr2.Interval = 100;
tmr2.Tick +=new EventHandler(tmr2_Tick);
tmr2.Start();
}
private void tmr2_Tick(object sender, EventArgs e)
{
label1.Text = System.Convert.ToString(System.Environment.TickCount);
}
回复 引用
goneaway@sohu.com
回复 引用
可以用timer控件的SynchronizingObject来和主线程中的对象做同步(比如form),或者用主线程中的对象的InvokeRequired()方法来判断是否要同步,再用form.Invoke()或form.BeginInvoke()在同一线程中回调。
回复 引用
因為其非主線程,至少也要用BeginInvoke & delegate
而且System.Threading.Timer也很損記憶體
在PC上沒感覺,但用在WinCE就感覺很苦惱
回复 引用