為你解決VB.NET定時器編程線程安全問題
經(jīng)過長時間學習VB.NET,對于它還是很了解的,在這里和大家分享一下關(guān)于VB.NET定時器編程,看完本文你肯定有不少收獲,希望本文能教會你更多東西。
VB.NET定時器編程
為了***限度的代碼重用,三種不同類型的定時器事件都調(diào)用了同樣的ShowTimerEventFired方法,下面就是三個定時器事件的處理函數(shù):
- 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方法采用當前時間和當前線程名字作為參數(shù)。為了區(qū)別工作者線程和UI線程,在例子程序的主入口點設(shè)置CurrentThread對象的名字屬性為"UIThread"。GetThreadName幫助函數(shù)返回Thread.CurrentThread.Name值或者當Thread.CurrentThread.IsThreadPoolThread屬性為真時返回"WorkerThread"。
因為System.Timers.Timer和System.Threading.Timer的定時器事件都是在工作者線程上執(zhí)行的,所以在事件處理函數(shù)中的任何用戶交互代碼都不是馬上進行的,而是被列集等候返回到UI線程上進行處理。為了這樣做,我創(chuàng)建了一個ShowTimerEventFiredDelegate委托調(diào)用:
- private delegate void ShowTimerEventFiredDelegate (DateTime eventTime, string threadName);
ShowTimerEventFiredDelegate允許ShowTimerEventFired方法在UI線程上調(diào)用它自己,顯示了發(fā)生這一切的代碼。
通過查詢InvokeRequired屬性可以非常容易的知道你是否從當前線程可以安全的訪問Windows窗體控件。在這個例子中,如果列表框的InvokeRequired屬性為真,窗體的BeginInvoke方法就可以被ShowTimerEventFired方法調(diào)用,然后再被ShowTimerEventFiredDelegate方法調(diào)用。這能夠保證列表框的Add方法在UI線程上執(zhí)行。
正如你所看到的,當你編寫異步定時器事件時有許多問題需要意識到。在使用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月份的期刊上。上述是一個關(guān)于VB.NET定時器編程線程安全上的問題的分析,提到的問題大家在編程中要注意。
【編輯推薦】