c#執行定時計算限制操作(計時器)

來源:互聯網
上載者:User

在.Net Framework Class Library(FCL)中,System.Threading命名空間下定義了一個Timer類,這就是常用的一個計時器。實際上FCL總共提供了如下幾種計時器:

1、System.Threading.Timer

在實際的開發中,這個類出現和使用頻率非常高,下面就重點談談它的一些基礎概念和應用執行個體。

(1)、常用的構造器

      public Timer(TimerCallback callback, object state, int dueTime, int period);      public Timer(TimerCallback callback, object state, long dueTime, long period);      public Timer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period);      public Timer(TimerCallback callback, object state, uint dueTime, uint period);

參數說明:

a、callback:望文生意,肯定表示一個回調,它是標識希望由一個線程池線程回調的方法。當然它的類型必須和System.Threading.TimerCallback委託類型匹配,如下所示:

 public delegate void TimerCallback(object state);

b、state:每次調用回調方法,向回調方法傳遞的狀態資料,如沒有,可以為null;

c、dueTime:在首次調用回調方法之前要等待多少毫秒。如希望立刻調用回調方法,該參數指定為0即可。

d、period:指定了以後每次調用回調方法之前要等待多少毫秒(理解成下一次和本次調用的時間間隔即可)。如果為該參數傳遞Timeout.Infinite(或者直接寫-1),線程池線程只調用回調方法一次(那也就沒有必要用計時器了)。

 

(2)、基本工作原理

在內部(原文應該指CLR內),線程池為所有Timer對象只使用了一個線程。這個線程知道下一個Timer對象在什麼時候到期(計時器還有多久觸發)。下一個Timer對象到期時,線程就會喚醒,在內部調用ThreadPool的QueueUserWorkItem,將一個工作項目添加到線程池的隊列中,使你的回調方法得到調用。

注意:如果回調方法的執行時間很長,計時器可能在上個回調還沒有完成的時候再次觸發(對於執行時間很長的任務,實際開發中通常不使用線程池,而是直接使用new一個Thread)。這可能會造成多個線程池線程同時調用你的方法(方法的重疊覆蓋?)。為瞭解決這個問題,Jeffrey Richter建議我們這樣使用Timer:

a、為period指定Timeout.Infinite。這樣,計時器就只觸發一次;

b、在回調方法中,調用Timer的Change方法來指定一個新的dueTime,並再次為period指定Timeout.Infinite。Change方法的幾個重載版本:

        public bool Change(int dueTime, int period);             public bool Change(long dueTime, long period);                public bool Change(TimeSpan dueTime, TimeSpan period);        public bool Change(uint dueTime, uint period);

Timer還有一個Dispose方法,允許完全取消計時器。

(3)、範例程式碼

internal static class TimerDemo{    private static Timer s_timer;    public static void Main()    {        Console.WriteLine("Main thread: starting a timer");        using (s_timer = new Timer(ComputeBoundOp, 5, 0, Timeout.Infinite))        {            Console.WriteLine("Main thread: Doing other work here...");            Thread.Sleep(10000);  // Simulating other work (10 seconds)        } // Calls Dispose to cancel the timer now        Console.Read();    }    // This method's signature must match the TimerCallback delegate    private static void ComputeBoundOp(Object state)    {        // This method is executed by a thread pool thread        Console.WriteLine("In ComputeBoundOp: state={0}", state);        Thread.Sleep(1000);  // Simulates other work (1 second)        // Have the Timer call this method again in 2 seconds        s_timer.Change(2000, Timeout.Infinite);        // When this method returns, the thread goes back        // to the pool and waits for another work item    }}

這個樣本是<<CLR via C#>>中的源碼,雖然簡單,卻貫穿實現了建立Timer,Timer定時工作到Timer的銷毀一整個生命週期。using語句我們可以使用try finally替換,在finally語句塊中顯式調用Dispose方法。注意,程式中輸出了四次“In ComputeBoundOp: state=5”,您不妨多想一想為什麼只有4次。而如果我們把Main方法的這一行:

            Thread.Sleep(10000);  // Simulating other work (10 seconds)

注釋掉,程式有時候會拋出“程式無法訪問已釋放對象”的異常,而且每次輸出的結果可能還不一樣。之所以這麼說,是因為using語句不能保證靜態Timer立刻被記憶體回收行程回收。您不妨自己動手一試。

 

2、System.Timers.Timer

這個類據說基本上就是System.Threading.Timer的封裝過的“整過容的副產品”。當計時器到期觸發時,會導致CLR將事件放到線程池的隊列中。該類派生自System.ComponentModel的Component類,允許VS將計時器對象放到設計平面上,並公開了它的屬性和事件(不就是一個控制項嗎,難道?)。

 

3、System.Windows.Forms.Timer

構造一個該類的執行個體,相當於告訴Windows將一個計時器和調用線程關聯。當這個計時器被觸發時,Windows將一條及時訊息注入線程的訊息佇列。線程必須執行一個訊息泵來提取這些訊息,並把它們派遣給想要的回調方法。注意,所有這些工作都只由一個線程完成——設定計時器的線程保證就是執行回調方法的線程。這還意味著你的計時器方法不會由多個線程並發執行。

 

4、System.Windows.Threading.DispatcherTimer

這個類是System.Windows.Forms的Timer在WPF和SilverLight應用程式中的等價物。通俗地說,這個類也就是System.Windows.Forms的Timer在WPF和SilverLight下的一個馬甲。擅於改頭換面新瓶裝舊酒在MS的技術領域中也不是一天兩天的事情了。

 

在Jeffrey Richter 的<<CLR via C#>>中關於計時器有很精練的說明,其中他說“事實上,我個人從來不用System.Timers.Timer類,建議你也不要用它”,他的這種態度蠻好玩的。反正對於這個類我倒是用過不少,而且一直沒出過什麼差錯,就算是”山寨“或者”馬甲“也不是從來都是一無是處。

 

參考:

Jeffrey Richter <<CLR via C#>>

http://msdn.microsoft.com/zh-cn/library/system.threading.timer.aspx

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.