Wednesday, October 08, 2008 - 文章

CODE-關於Response.Flush的小小測試

同事要用網頁跑一段很久的程序,因此想用"簡便"的方法產生即時狀態更新的效果,以免使用者等到抓狂。(簡便->代表用最少的Code做出需要的功能,有沒有用到又酷又炫的AJAX,架構、程式漂亮與否是其次)

我想到最簡單的方法是在這段要執行很久的ASP.NET中,用Response.BufferOutput = false加上Response.Write("..")、Response.Flush(),每執行到一個段落,輸出一部分內容來更新狀態。

於是我寫了以下的Sample Code:

<%@ Page Language="C#" %>
<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.BufferOutput = false;
        Response.Flush();
        for (int i = 1; i < 10; i++)
        {
            Response.Write("<li>" + i.ToString());
            Response.Flush();
            System.Threading.Thread.Sleep(1000);
        }
        Response.Write("</body></html>");
        Response.End();
    }
</script>
<html">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    </form>
</body>
</html>

在我的機器上測試成功後,丟給同事測試,傳來結果卻是最後才一次輸出所有數字。

自己將程式放到不同機器反覆測試了一下,發現有趣的現象: 這段程式有時可以陸續印出1, 2, 3, 4、有時則會等到最後才一次印出。而且往往第一次執行不OK,但按下IE的重新載入卻又成功。

會不會問題出在瀏覽器端?

於是我用HttpWatch進行觀察,驗證了我的猜測,在成功與失敗兩種情況中,資料都有陸續送至瀏覽器,但卻分別得到陸續印出或一次印出兩種結果。

我又另外試了Firefox及Chrome,得到更有趣的結果: Firefox永遠陸續印出,Chrome則永遠一次印出。

我大膽推論,當收到的HTML碼還不完整時,要不要Render出元素出來,取決於Browser。Firefox選擇了收到立即處理,Chrome則是等收齊再說。而IE最彈性,當發現接收資料的速率較慢時,怕會收到太多破碎不完整的HTML片段做白工,選擇收集齊再產出;當接收速度不差時,就採行收到立即處理。這個推論可以解釋,為何在本機總是成功,在遠端第一次失敗,Reload會成功,但是否為真我就不敢確定了。

當HTML不完整時,各瀏覽器的處理原則不一,看來這個方法並不理想。我想到另一招,<script>中的段落應該都會即時處理才對,所以將程式修改如下:

<%@ Page Language="C#" %>
<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.BufferOutput = false;
        Response.Clear();
        Response.Write("<html><body><span id='spnDisp'></span>");
        Response.Flush();
        for (int i = 1; i < 10; i++)
        {
            Response.Write("<script type='text/javascript'>");
            Response.Write("document.getElementById('spnDisp').innerHTML='" 
+ i.ToString() + "';");
            Response.Write("</" + "script>");
            Response.Flush();
            System.Threading.Thread.Sleep(1000);
        }
        Response.Write("</body></html>");
        Response.End();
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    </form>
</body>
</html>

Bingo!! 使用IE, Firefox, Chrome測試都可成功運作! 不過我還是不確定,會不會在某些特例下失常? 大家看看還有沒有什麼點子,歡迎討論。

搜尋

Go

<October 2008>
SunMonTueWedThuFriSat
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678
 
RSS
【工商服務】
最新回應

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


BlogLook Score and Rank

Syndication