熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

技巧:.Net框架類庫中定時器類的使用[2]

2022-06-13   來源: .NET編程 

  對SystemWindowsFormsTimer的編程不能再簡單了——它有一個非常簡單和可直接編程的接口Start和Stop方法實際上提供了一個設置使能屬性的改變方法(其本身是對Win?的SetTimer和KillTimer功能的一個包裝)我剛才提到的間隔屬性名字本身就說明了問題即使技術上你可以設置間隔屬性低到毫秒但你應該知道在NET框架文檔中指出這個屬性大約精確到毫秒(假定UI線程對於處理是可用的)

  捕捉由SystemWindowsFormsTimer類實例引發的事件是通過感知一個標准的EventHandler委托的標記事件來處理的就像下面的代碼片斷所示

SystemWindowsFormsTimer tmrWindowsFormsTimer = new SystemWindowsFormsTimer();tmrWindowsFormsTimerInterval = ;tmrWindowsFormsTimerTick += new EventHandler(tmrWindowsFormsTimer_Tick);tmrWindowsFormsTimerStart();private void tmrWindowsFormsTimer_Tick(object sender SystemEventArgs e){ //Do something on the UI thread}
  SystemTimersTimer

  NET框架文檔指出SystemTimersTimer類是一個服務器定時器是為多線程環境進行設計和優化該定時器類的實例能夠被多個線程安全地訪問不像SystemWindowsFormsTimerSystemTimersTimer缺省的將在一個工作者線程上調用你的定時器事件處理函數該工作者線程是從公共語言運行時(CLR)線程池中獲得這意味著在你的逝去的時間處理函數代碼中必須遵從Win編程的黃金規則除了創建該控件實例的線程之外一個控件的實例從來不被任何其它的線程所訪問

  SystemTimersTimer提供了一個簡單的方法處理這樣的困境——暴露一個公共的SynchronizingObject屬性把該屬性設置為一個窗體實例(或者窗體上的一個控件)將保證你的事件處理函數代碼運行在SynchronizingObject被實例化的同一個線程裡

  如果你使用了Visual Studio NET工具箱Visual Studio NET自動的設置SynchronizingObject屬性為當前的窗體實例首先它設定該定時器的SynchronizingObject屬性使其在功能上同SystemWindowsFormsTimer類一樣對於大部分功能的確是這樣當操作系統通知SystemTimersTimer類所允許的定時時間已過去定時器使用SynchronizingObjectBeginInvoke方法在一個線程上去執行事件委托該線程是創建SynchronizingObject的線程事件處理函數將被阻塞直到UI線程能夠處理它然而不像SystemWindowsFormsTimer類一樣該事件最終仍然能夠被引發像你在Figure 中看到的當UI線程不能夠處理時SystemWindowsFormsTimer不會引發事件可是當UI線程可用時SystemTimersTimer卻會排隊等候處理

  Figure 是如何使用SynchronizingObject屬性的例子使用例子程序並通過選擇SystemTimersTimer的radio按鈕你可以分析這個類並按照執行SystemWindowsFormsTimer類行為的同樣順序運行該類這樣就會產生Figure 的輸出結果

  正如你所看到的它不會跳過一個跳動——即使UI線程在睡眠在每一個事件間隔就有一個時間消失事件處理會被排隊執行因為UI線程在睡眠所以當UI線程一旦被喚醒例子程序就會列出個定時器事件()並能夠處理處理函數

  正如我早先提到的SystemTimersTimer類成員非常類似與SystemWindowsFormsTimer最大的區別就在與SystemTimersTimer類是對Win可等待定時對象的一個包裝並在工作者線程上產生一個時間片消失事件而不是在UI線程上產生一個時間標記事件時間片消失事件必須與一個同ElapsedEventHandler委托像匹配的事件處理函數相連接事件處理函數接受一個ElapsedEventArgs類型的參數

  除了標准的EventArgs成員ElapsedEventArgs類暴露了一個公共的SignalTime屬性它包含了一個精確的定時器時間片消失的時間因為這個類支持不同線程的訪問除了時間消失事件所在的線程應該相信它的Stop方法能夠被其它線程所調用這會潛在的導致消失事件被引發即使其Stop方法已經被調用你可以把SignalTime和Stop方法調用的時間進行比較來解決這個問題

  SystemTimersTimer也提供了AutoReset屬性來決定當時間片消失事件引發後是繼續進行還是只這一次要記住在定時器開始後重設間隔屬性會導致當前計數為比如設置了一個秒的間隔在間隔被改變為秒時秒已經過去了那麼下一個定時器事件將會在上一個定時器事件秒後發生

 SystemThreadingTimer

  第三個定時器類來自SystemThreading名字空間我願意說這是所有定時器類中最好的一個但這會引起誤導舉一個例子我驚訝的發現對於駐留在SystemThreading名字空間的這個類天生就不是線程安全的(很明顯這不意味著它不能以線程安全的方式使用)這個類的可編程接口同其它兩個類也不一致它稍微有點麻煩

[]  []  []  []  


From:http://tw.wingwit.com/Article/program/net/201311/15304.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.