http://shansun123.javaeye.com/blog/550155
通过使用System.Timers.Timer,就可以解决这个问题。因为System.Timers.Timer是在.NET的Thread Pool上面运行的,而不是直接在UI Thread上面运行,所以在这种Timer的EventHandler里面进行耗时较长的计算不会导致UI失去响应。但是这里有两个地方需要注意:
- 因为一般来说System.Timers.Timer不是运行在UI Thread上面的,所以如果要在这种Timer的EventHandler里面更新UI元素的话,需要进行一次线程切换,在WinForm开发中一般通过UI元素的Invoke方法完成:
- System.Timers.Timer有一个Property:SynchronizingObject 。如果设置了这个Property(一般是某个Form),那么之后对Timer挂接的EventHandler的调用将会在创建这个UI元素的线程上进行(一般来说就是UI线程)。值得注意的是,如果你通过WinForm设计器把System.Timers.Timer拖放到Form上,那么这个Property将会自动被设置。此时这种Timer就和System.Windows.Forms.Timer的效果一样:长调用将会阻塞界面。
在 Visual Studio .NET 中有两种计时器控件——基于服务器的计时器和标准的基于 Windows 的计时器。
基于 Windows 的计时器为在 Windows 窗体应用程序中使用而进行了优化,基于服务器的计时器是传统的计时
器为了在服务器环境上运行而优化后的更新版本。
二、两种不同的计时器有什么区别呢?
在 Win32 体系结构中有两种类型的线程:UI 线程和辅助线程。UI 线程绝大多数时间处于空闲状态,等待
消息循环中的消息到来。一旦接收到消息,它们就进行处理并等待下一个消息到来。另外,辅助线程用来执
行后台处理而且不使用消息循环。虽然 Windows 计时器和基于服务器的计时器运行时都使用 Interval 属性,
但它们的设计用途是不同的(这一点可由它们对线程的处理方式来证明):
Windows 计时器是为单线程环境设计的,其中,UI 线程用于执行处理。 Windows 计时器的精度限定为 55
毫秒。这些传统计时器要求用户代码有一个可用的 UI 消息泵,而且总是在同一个线程中操作,或者将调用封
送到另一个线程。对于 COM 组件来说,这样会降低性能。
基于服务器的计时器是为在多线程环境下与辅助线程一起使用而设计的。由于它们使用不同的体系结构,因
此基于服务器的计时器可能比 Windows 计时器精确得多。服务器计时器可以在线程之间移动来处理引发的事件。
基于服务器的 Timer 是为在多线程环境中用于辅助线程而设计的。服务器计时器可以在线程间移动来处理引
发的 Elapsed 事件,这样就可以比 Windows 计时器更精确地按时引发事件。有关基于服务器的计时器的更多信
息,请参阅基于服务器的计时器介绍。
1、服务器计时器使用示例
System.Timers.Timer aTimer = new System.Timers.Timer();
//设置事件处理句柄,此处为OnTimedEvent方法:
aTimer.Elapsed+=new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval=5000;//设置间隔时间为5秒
aTimer.AutoReset=true;
/*
*注意 当 AutoReset 设置为 false 时,Timer 只在第一个 Interval
*过后引发一次 Elapsed 事件。若要保持以 Interval 时间间隔引发
*Elapsed 事件,请将 AutoReset 设置为 true。
*/
aTimer.Enabled=true;//计时开始,此处也可以用aTimer.Start();
2、Windows 计时器使用示例
Windows 计时器是为单线程环境设计的,其中,UI 线程用于执行处理。它要求用户代码有一个可用的 UI
消息泵,而且总是在同一个线程中操作,或者将调用封送到另一个线程。
.NET Framework里面提供了三种Timer:
- System.Windows.Forms.Timer
- System.Timers.Timer
- System.Threading.Timer
Visual Studio 2003的工具箱里面默认提供了System.Windows.Forms.Timer和System.Timers.Timer两种,而Visual Studio 2005中确只默认提供了System.Windows.Forms.Timer这一种。这里简单的介绍一下这两种Timer的区别。
System.Windows.Forms.Timer是使用得比较多的Timer,Timer Start之后定时(按设定的Interval)调用挂接在Tick事件上的EvnetHandler。在这种Timer的EventHandler中可以直接获取和修改UI元素而不会出现问题--因为这种Timer实际上就是在UI线程自身上进行调用的。也正是因为这个原因,导致了在Timer的EventHandler里面进行长时间的阻塞调用,将会阻塞界面响应的后果。
******************************************************
timerXXX.Stop();
Thread thread = new Thread(new ThreadStart(target));
thread.Start()
在方法target中适当的时刻,timerXXX.Start()
不过不涉及操作主线程CONTROL时,更方便,效果更好。
会遇到两个问题: 假如线程池已满(所有的线程都在运行中),那么这个请求排到队列中等待,而且定时器不在精确。
假如创建了多个定时器,线程池会因为等待它们时间片失效而非常忙。
================================================
http://hi.baidu.com/563944808/blog/item/9c5633020c68dd84d43f7c82.html