ASP.NET組件設計之ASP.NET Timer淺析
ASP.NET組件設計之ASP.NET Timer一、思考組件需求
在網頁上編寫一個Timer組件,首先得解決這個問題:如何讓網頁定時Post回Server端。 正常情況下這個動作是由用戶按下某個按鈕后觸發的,但Timer組件的需求是自動在特定時間觸發,例如設計者設定在每5秒產生一個Post動作,網頁就得每5秒做出一個Post動作,這該如何完成呢?事實上,這可以通過Javascript提供的一個setTimeout函數來完成,只要運用此函數每5秒調用一次由ASP.NET產生的_doPostBack函數即可達到定時自動Post的需求,下面是setTimeout函數的原型。
- setTimeout(﹤function﹥,﹤interval﹥);
***個參數是當Timeout時間到時所調用的函數,第二個是Timeout時間的長度,單位是毫秒(millisecond)。解決網頁定時自動Post的問題后,接著就是Server端如何接收這個信息的問題,答案就是Post-Back機制,只要實現此機制,組件就能在網頁自動Post后取得主控權,并引發用戶所掛載的事件函數。
ASP.NET組件設計之ASP.NET Timer二、實現Post-Back與繪制JavaScript
現在我們面臨兩個問題:***是組件的基類選擇。由于WebTimer屬于不可視組件,并不需要任何外觀睥屬性,所以自然是繼承自Control類;第二是WebTimer必須實現Post-Back接口,宋才能在網頁自動Post取得主控權后觸發用戶所掛載的事件函數。 下面是WebTimer處理Post-Back機制的部分程序代碼
- public class WebTimer:Control,IPostBackEventHandler
- {
- …………
- IPostBackEventHandler implements#region IPostBackEventHandler implements
- void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
- {
- OnTimer(EventArgs.Empty);
- }
- #endregion
- …………
- }
由程序易知,WebTimer繼承自Control類,同時實現了IPostBackEventHandler接口。當組件實現了該接口之后,Post-Back發生時Page對象會一一調用已注冊參與Post-Back運作組件的IPostBackEventHandler.RaisePostBackEvent函數,此處WebTimer組件調用了OnTimer函數將控制權轉交給設計者所綁定的事件上,下面是OnTimer函數及事件處理部分的代碼:
- private static readonly object EventTimer = new object();
- …………
- Events#region Events
- public event EventHandler Timer
- {
- add{Events.AddHandler(EventTimer,value);}
- remove{Events.RemoveHandler(EventTimer,value);}
- }
- #endregion
- event handler functions#region event handler functions
- protected virtual void OnTimer(EventArgs e)
- {
- EventHandler timerHandler = (EventHandler)Events[EventTimer];
- if(null != timerHandler)
- {
- timerHandler(this,e);
- }
- }
- #endregion
接下來要做的就是繪制JavaScript函數。在這之前,還有一件很重要的事,那就是繪制默認的_doPostBack函數。默認情況下Page對象為了節省帶寬,并不是每次都繪制此函數。只有在某個組件明確調用Page.GetPostBackEventReference或Page.GetPostBackClientHyperlink其中的一個函數時,_doPostBack函數才會被繪制到網頁中。因此,WebTimer組件必須得調用Page.GetPostBackEventReference或是Page.GetPostBackClientHyperlink函數,但是在哪里調用呢?Render函數?不行!此時Page對象已經進入繪制狀態,在此時調用Page對象的任何函數都已經太遲了,所以***的地方是調用OnPreRender函數,下面是相關代碼:
- protected override void OnPreRender(EventArgs e)
- {
- base.OnPreRender(e);
- //call this method to ensure that the _doPostBack method will be called
- Page.ClientScript.GetPostBackEventReference(this,"");
- }
接下來就是編寫JavaScript函數并在Render函數中繪制相關動作:
- Utility functions#region Utility functions
- private string BuildJavaScript()
- {
- StringBuilder sb = new StringBuilder();
- sb.Append("\n﹤script language=\"javascript\"﹥\n ﹤!-- ");
- sb.AppendFormat("\n setTimeout(\"{0}\",{1});",
- new object[]{this.Page.GetPostBackEventReference(this),interval.ToString()});
- sb.Append("\n //--﹥\n﹤/script﹥");
- return sb.ToString();
- }
- #endregion
- protected override void Render(HtmlTextWriter writer)
- {
- /**//*to ensure that this component is in the "runat=server" HtmlForm,
- or there'll be no Post-Back event,as a result that this component will be of no avail
- */
- if(null != Page)
- Page.VerifyRenderingInServerForm(this);
- if(enabled)
- writer.Write(BuildJavaScript());
- }
除了Render函數之外,程序中尚用到兩個函數:Page.VerifyRenderingInServerForm函數用來確認組件位于標記為”runat=server”的HtmlForm控件中,假如組件并非位于此類的HtmlForm中,那么也就沒有Post-Back帶傷,WebTimer組件自然也就沒有作用了。另外一個是BuildJavaScript,此函數將之前所討論的JavaScript函數setTimeout配合用戶所設定的時間繪出。
有一點要指出來的是,在.net 2.0里面會有個警告提示System.Web.UI.Page.GetPostBackEventReference(System.Web.UI.Control)已過時,建議用ClientScript.GetPostBackEventReference來代替,新的函數重載了四次,但是沒有一個參數的,現在還不知道怎么改,有知道的希望能指出來!
ASP.NET組件設計之ASP.NET Timer的基本情況就向你介紹到這里,希望對你學習有所幫助。
【編輯推薦】