官术网_书友最值得收藏!

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í)期的畫面。

true

圖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等較高效率的手法完成同樣的工作。

主站蜘蛛池模板: 淮滨县| 建阳市| 宁远县| 盐池县| 金平| 罗定市| 上饶市| 鲜城| 宁晋县| 陵川县| 曲周县| 阳西县| 江阴市| 乌恰县| 泸定县| 平罗县| 江陵县| 白朗县| 滁州市| 永昌县| 邹城市| 大洼县| 武胜县| 灵璧县| 保山市| 临海市| 师宗县| 观塘区| 华容县| 林周县| 宁都县| 河源市| 蒙阴县| 巫山县| 独山县| 金昌市| 若羌县| 广河县| 石泉县| 九龙城区| 嘉义市|