同事要用網頁跑一段很久的程序,因此想用"簡便"的方法產生即時狀態更新的效果,以免使用者等到抓狂。(簡便->代表用最少的Code做出需要的功能,有沒有用到又酷又炫的AJAX,架構、程式漂亮與否是其次)
我想到最簡單的方法是在這段要執行很久的ASP.NET中,用Response.BufferOutput = false加上Response.Write("..")、Response.Flush(),每執行到一個段落,輸出一部分內容來更新狀態。
<%@ 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的重新載入卻又成功。
我大膽推論,當收到的HTML碼還不完整時,要不要Render出元素出來,取決於Browser。Firefox選擇了收到立即處理,Chrome則是等收齊再說。而IE最彈性,當發現接收資料的速率較慢時,怕會收到太多破碎不完整的HTML片段做白工,選擇收集齊再產出;當接收速度不差時,就採行收到立即處理。這個推論可以解釋,為何在本機總是成功,在遠端第一次失敗,Reload會成功,但是否為真我就不敢確定了。
<%@ 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>