System.Threading.Timer类的TimerCallback 委托
?
System.Threading.Timer類的TimerCallback 委托
?
Written by: Rickie Lee
Nov. 19, 2004
System.Threading.Timer 是一個使用回調方法的計時器,而且由線程池線程服務,簡單且對資源要求不高。
?
只要在使用 Timer,就必須保留對它的引用。對于任何托管對象,如果沒有對 Timer 的引用,計時器會被垃圾回收。即使 Timer 仍處在活動狀態,也會被回收。當不再需要計時器時,請使用 Dispose 方法釋放計時器持有的資源。
?
使用 TimerCallback 委托指定希望 Timer 執行的方法。計時器委托在構造計時器時指定,并且不能更改。此方法不在創建計時器的線程中執行,而是在系統提供的線程池線程中執行。
?
創建計時器時,可以指定在第一次執行方法之前等待的時間量(截止時間)以及此后的執行期間等待的時間量(時間周期)??梢允褂?/span> Change 方法更改這些值或禁用計時器。
?
Demo application:
應用場景:在windows form程序自動執行某項工作后,希望其windows form能夠自動關閉。
代碼設計:(1)首先聲明Timer變量:
private System.Threading.Timer timerClose;
?
(2)在上述自動執行代碼后面添加如下Timer實例化代碼:
// Create a timer thread and start it
timerClose = new System.Threading.Timer(new TimerCallback(timerCall), this, 5000, 0);
?
Timer構造函數參數說明:
Callback:一個 TimerCallback 委托,表示要執行的方法。
State:一個包含回調方法要使用的信息的對象,或者為空引用(Visual Basic 中為 Nothing)。
dueTime:調用 callback 之前延遲的時間量(以毫秒為單位)。指定 Timeout.Infinite 以防止計時器開始計時。指定零 (0) 以立即啟動計時器。
Period:調用 callback 的時間間隔(以毫秒為單位)。指定 Timeout.Infinite 可以禁用定期終止。
?
(3)定義TimerCallback委托要執行的方法:
private void timerCall(object obj)
{
????? timerClose.Dispose();
????? this.Close();
}
?
當然,除了使用上述System.Threading.Timer類的TimerCallback 委托機制外,應該還有很多其他的辦法。另外,這里只是demo了TimerCallback委托的簡單應用。
?
Appendix about the article
在讀一段關于Design Pattern的代碼時,看到使用Timer類TimerCallback委托,隨并記錄下來。
?
Reference:
1, MSDN, System.Threading.Timer class
posted on 2004-11-20 11:27 Rickie 閱讀(5590) 評論(16) ?編輯 收藏 網摘 所屬分類: D.多線程技術評論
166.111.33.* 2004-11-20 11:45 ? 試試沒有注冊的用戶能不能發文謝謝
??????????
2004-11-20 22:22 ? 用Threading.Timer來完成“應用場景:在windows form程序自動執行某項工作后,希望其windows form能夠自動關閉?!?
1. 好像大材小用了。
2. 由線程池執行WinForm控件(包括Form)的方法非常危險!因為這些方法只能由創建該窗口控件的線程執行。
3. 由線程池線程服務,資源要求不高的說法是有問題的,因為 a)需要線程切換;b)需要創建windows核心對象。
總之,System.Threading.Timer改成System.Windows.Forms.Timer更加合適
??????????
[樓主] 2004-11-22 06:23 ? Thank you, msolap.
*
1. 好像大材小用了。
是的,這里只是提供一個簡單的Demo演示一下而已。 2. 由線程池執行WinForm控件(包括Form)的方法非常危險!因為這些方法只能由創建該窗口控件的線程執行。
Sorry,沒有很明白你的意思,希望可以進一步闡述,謝謝。
*
根據Microsoft的文檔:TimerCallback委托聲明的回調方法,不在創建計時器的線程中執行(創建計時器的線程也就是創建該窗口控件的線程),而是在系統提供的線程池線程中執行。3. 由線程池線程服務,資源要求不高的說法是有問題的,因為 a)需要線程切換;b)需要創建windows核心對象。 System.Threading.Timer 是一個使用回調方法的計時器,而且由線程池線程服務,簡單且對資源要求不高--這是源于Microsoft的說法(也有可能Microsoft的說法不嚴謹)。
*
如果根據上述特定的Demo程序而言,正如你說言,System.Windows.Forms.Timer可能更合適。
msolap, 謝謝你的回復。
??????????
2004-11-22 16:36 ? 針對第2)點,說得直白一點就是所有窗口(包括上面的控件)只能由主線程執行,不能由其他線程執行。(窗口消息隊列是依附于窗口線程的)
第3)點,英文原文應該是
System.Threading.Timer is a simple, lightweight timer that uses callback methods and is served by threadpool threads.
lightweigth并非指對資源要求低,只是相對于過去常用的CreateWaitableTimer(Win32 SDK)而言低一點。
其實從貴文中第二段:“當不再需要計時器時,請使用 Dispose 方法釋放計時器持有的資源?!?就可以體會到它對資源的要求。:-)
??????????
[樓主] 2004-11-23 00:31 ? Thanks for your explanation. So far I really know what you mean on Point 2.
*
But why do you think it's very dangerous when doing it this way?
Thanks.
??????????
2004-11-23 23:33 ? 主線程肯定不會是線程池里的某個線程,所以在線程池里調用Form的this.Close(),危險!應該讓主線程調用才行。
??????????
[樓主] 2004-11-24 02:28 ? Thank you, msolap.
??????????
2005-08-23 11:43 ? 可以作為定時任務來完成,這是一個不錯的方式
??????????
61.141.195.* 2005-09-08 10:06 我遇到了一個問題,有個api函數,使用form.timer調用能夠正確的返回值,但使用threading.timer和threading.thread都不行,看來還是有區別的。qq9611153
????????
59.120.72.* 2006-01-06 17:54 請問一下以下code,為什麼Timer無法啟動呢?
謝謝
System.Windows.Forms.Timer tmr2 = new System.Windows.Forms.Timer();
private void button3_Click(object sender, System.EventArgs e)
{
System.Threading.ThreadStart thds = new ThreadStart(label);
System.Threading.Thread thd = new Thread(thds);
thd.Start();
}
private void label()
{
tmr2.Interval = 100;
tmr2.Tick +=new EventHandler(tmr2_Tick);
tmr2.Start();
}
private void tmr2_Tick(object sender, EventArgs e)
{
label1.Text = System.Convert.ToString(System.Environment.TickCount);
}
????????
222.90.119.* 2006-03-15 11:39 請問樓主有沒有解決代碼2的多線程問題?我也有這個代碼,并按照codeproject上面的方法嘗試解決多線程問題,但沒有成功。如果你有解決,希望能給一份修改后的源碼,不勝感激!!!
goneaway@sohu.com
????????
124.243.197.* 2007-04-16 01:33 Threading下的timer控件的回調函數的確是在線程池里運行的,在委托回調函數里直接訪問主線程創建的對象會拋出異常。
可以用timer控件的SynchronizingObject來和主線程中的對象做同步(比如form),或者用主線程中的對象的InvokeRequired()方法來判斷是否要同步,再用form.Invoke()或form.BeginInvoke()在同一線程中回調。
????????
220.133.45.* 2008-09-26 13:14 不能使用System.Threading.Timer去直接this.Close或label,會Exception
因為其非主線程,至少也要用BeginInvoke & delegate
而且System.Threading.Timer也很損記憶體
在PC上沒感覺,但用在WinCE就感覺很苦惱
????????
?
轉載于:https://www.cnblogs.com/qiantuwuliang/archive/2009/07/03/1516201.html
總結
以上是生活随笔為你收集整理的System.Threading.Timer类的TimerCallback 委托的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基金记事本
- 下一篇: 每日两句英语-7/7/2009