经过长时间学习VB.NET,对于它还是很了解的,在这里和大家分享一下关于VB.NET定时器编程,看完本文你肯定有不少收获,希望本文能教会你更多东西。
VB.NET定时器编程
为了***限度的代码重用,三种不同类型的定时器事件都调用了同样的ShowTimerEventFired方法,下面就是三个定时器事件的处理函数:
- private void tmrWindowsFormsTimer_Tick(object sender, System.EventArgse)
- {
- ShowTimerEventFired(DateTime.Now, GetThreadName());
- }
- private void tmrTimersTimer_Elapsed(object sender, System.TimersElapsedEventArgse){
- ShowTimerEventFired(DateTime.Now, GetThreadName());
- }
- private void tmrThreadingTimer_TimerCallback(object state){ ShowTimerEventFired(DateTime.Now, GetThreadName());
- }
正如你所看到的,ShowTimerEventFired方法采用当前时间和当前线程名字作为参数。为了区别工作者线程和UI线程,在例子程序的主入口点设置CurrentThread对象的名字属性为"UIThread"。GetThreadName帮助函数返回Thread.CurrentThread.Name值或者当Thread.CurrentThread.IsThreadPoolThread属性为真时返回"WorkerThread"。
因为System.Timers.Timer和System.Threading.Timer的定时器事件都是在工作者线程上执行的,所以在事件处理函数中的任何用户交互代码都不是马上进行的,而是被列集等候返回到UI线程上进行处理。为了这样做,我创建了一个ShowTimerEventFiredDelegate委托调用:
- private delegate void ShowTimerEventFiredDelegate (DateTime eventTime, string threadName);
ShowTimerEventFiredDelegate允许ShowTimerEventFired方法在UI线程上调用它自己,显示了发生这一切的代码。
通过查询InvokeRequired属性可以非常容易的知道你是否从当前线程可以安全的访问Windows窗体控件。在这个例子中,如果列表框的InvokeRequired属性为真,窗体的BeginInvoke方法就可以被ShowTimerEventFired方法调用,然后再被ShowTimerEventFiredDelegate方法调用。这能够保证列表框的Add方法在UI线程上执行。
正如你所看到的,当你编写异步定时器事件时有许多问题需要意识到。在使用System.Timers.Timer和System.Threading.Timer之前我推荐你阅读Ian Griffith的文章“Windows Forms:Give Your .NET-based Application a Fast and Responsive UI with Multiple Threads”, 该文刊登在MSDN杂志的2003年2月份的期刊上。上述是一个关于VB.NET定时器编程线程安全上的问题的分析,提到的问题大家在编程中要注意。
【编辑推荐】