- 決戰(zhàn).NET
- 黃忠成
- 975字
- 2018-12-27 16:55:57
3.4 真實(shí)進(jìn)度的呈現(xiàn):使用Timer與UpdatePanel控件
倘若某一個(gè)Async-Postback動(dòng)作需要花費(fèi)較多時(shí)間來處理,例如批次新增或轉(zhuǎn)文件等作業(yè),客戶多半不喜歡網(wǎng)頁就此停滯,而希望網(wǎng)頁能在運(yùn)行期間定時(shí)回報(bào)目前的處理進(jìn)度。以轉(zhuǎn)檔作業(yè)為例,以往實(shí)現(xiàn)這類需求時(shí),多半是將整個(gè)轉(zhuǎn)檔動(dòng)作放到Thread(線程)中,并產(chǎn)生一個(gè)工作ID,存放在事先創(chuàng)建于網(wǎng)頁中的Hidden Field內(nèi),用來作為訪問Cache信息的鍵值,當(dāng)Thread運(yùn)行時(shí),會(huì)依據(jù)此鍵值將進(jìn)度填入Cache中,網(wǎng)頁則是利用JavaScript的setTimeout函數(shù),定時(shí)做Postback,再在Server端所送上來的Hidden Field中取得工作ID,進(jìn)而取出Cache中的進(jìn)度信息顯示。時(shí)至今日,這種處理進(jìn)度回報(bào)的流程仍然可行,不過有了UpdatePanel及Timer等控件的協(xié)助,定時(shí)Postback的動(dòng)作便可輕松升級為定時(shí)Async-Postback動(dòng)作,讓客戶不會(huì)再有網(wǎng)頁畫面閃動(dòng)的不舒服感受,請照著下列步驟做。
1. 創(chuàng)建一個(gè)新網(wǎng)頁,命名為AsyncPostbackProgressReport.aspx。
2. 在頁面中放入ScriptManager控件。
3. 放入U(xiǎn)pdatePanel控件,命名為UpdatePanel1。
4. 將UpdatePanel1控件的UpdateMode屬性設(shè)為Conditional。
5. 放一個(gè)Timer控件至UpdatePanel1控件中,命名為Timer1,設(shè)定Interval屬性為2000,也就是每兩秒做一次Async-Postback動(dòng)作。
6. 設(shè)定Timer1控件的Enabled屬性為False。
7. 放一個(gè)Button控件至UpdatePanel1控件中,命名為Button1,Text設(shè)為Run。
8. 放一個(gè)Label控件至UpdatePanel1控件中,命名為Label1,Text屬性設(shè)為空白。
9. 放一個(gè)Button控件至UpdatePanel1控件中,命名為Button2,Text設(shè)為Cancel。
10. 在Timer1控件的Click事件中鍵入程序3-10中Timer1_Tick函數(shù)內(nèi)的代碼。
11. 在Button1控件的Click事件中鍵入程序3-10內(nèi)Button1_Click函數(shù)中的代碼。
12. 在Button2控件的Click事件中鍵入程序3-10內(nèi)Button2_Click函數(shù)中的代碼。
程序3-10
Samples\3\AjaxDemo1\AsyncPostbackProgressReport.aspx.cs using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.Threading; public partial class AsyncPostbackProgressReport : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void Timer1_Tick(object sender, EventArgs e) { //由Cache中取出進(jìn)度信息 TaskInformation info = Cache[TaskID_Hidden.Value] as TaskInformation; if (info != null) Label1.Text = string.Format("Processing {0}%", info.CurrentProgress); else { Label1.Text = string.Empty; Button1.Enabled = true; Timer1.Enabled = false; Button2.Visible = false; } } protected void Button1_Click(object sender, EventArgs e) { Thread th = new Thread(new ParameterizedThreadStart(Work)); //產(chǎn)生一個(gè)GUID,放到Hidden Field中,作為取得回報(bào)進(jìn)度信息的鍵值 TaskID_Hidden.Value = Guid.NewGuid().ToString(); //創(chuàng)建TaskInformation對象,并將其放入Cache中。 TaskInformation info = new TaskInformation(); info.CurrentProgress = 0; Cache[TaskID_Hidden.Value] = info; th.IsBackground = true; Timer1.Enabled = true; Button1.Enabled = false; Button2.Visible = true; Label1.Text = "Processing"; th.Start(TaskID_Hidden.Value); } private void Work(object state) { for (int i = 0; i < 10; i++) { System.Threading.Thread.Sleep(2000); //定時(shí)更新Cache中的進(jìn)度信息對象,如果Cacnel被設(shè)為True,那么立即停止工作 TaskInformation info = Cache[(string)state] as TaskInformation; if (info.Cacnel) break; info.CurrentProgress = i * 10; Cache[(string)state] = info; } //工作完成后,移除Cache中的進(jìn)度信息對象 Cache.Remove((string)state); } protected void Button2_Click(object sender, EventArgs e) { //取消時(shí),將Cache中的TaskInformation之Cancel設(shè)為True。 TaskInformation info = Cache[TaskID_Hidden.Value] as TaskInformation; info.Cacnel = true; Button2.Visible = false; Label1.Text = "Canceling...."; } } [Serializable] public class TaskInformation { public int CurrentProgress; public bool Cacnel; }
圖3-9是運(yùn)行時(shí)期的畫面。

圖3-9
關(guān)于進(jìn)度回報(bào)
使用Timer控件實(shí)現(xiàn)進(jìn)度回報(bào)并不算是個(gè)好主意,因?yàn)樗鼤?huì)一直運(yùn)行Async-Postback動(dòng)作,每次都會(huì)送出整個(gè)頁面的ViewState到Server端,這是相當(dāng)?shù)托实氖址ǎ竺娴恼鹿?jié)會(huì)采用PageMethods/Web Servcies等較高效率的手法完成同樣的工作。
- Instant Raspberry Pi Gaming
- Splunk 7 Essentials(Third Edition)
- Cinema 4D R13 Cookbook
- Getting Started with Oracle SOA B2B Integration:A Hands-On Tutorial
- 返璞歸真:UNIX技術(shù)內(nèi)幕
- 數(shù)據(jù)產(chǎn)品經(jīng)理:解決方案與案例分析
- 工業(yè)機(jī)器人入門實(shí)用教程(KUKA機(jī)器人)
- Machine Learning with the Elastic Stack
- 從零開始學(xué)PHP
- 大數(shù)據(jù)技術(shù)基礎(chǔ):基于Hadoop與Spark
- Extending Ansible
- ASP.NET 2.0 Web開發(fā)入門指南
- MPC5554/5553微處理器揭秘
- 計(jì)算機(jī)硬件技術(shù)基礎(chǔ)(第2版)
- 從機(jī)器學(xué)習(xí)到無人駕駛