现在的位置: 首页 > 综合 > 正文

使用Response.Flush方法实时显示处理过程的状态信息(转)

2012年02月04日 ⁄ 综合 ⁄ 共 4519字 ⁄ 字号 评论关闭

Web项目,在处理大数据量和复杂业务的情况下,用户在浏览器中点击一个按钮后,服务器需要处理几十秒甚至好几分钟,才能将处理结果反馈给用户,在这个漫长的等待过程中,用户面对毫无反应的浏览器会不知所措,即便提示用户正在处理,用户由于不知道服务器的处理状态,在长时间等待后,也会不耐烦或误以为操作失败,而去刷新或者关闭浏览器。

怎么应对这种状态,给用户一个更好的体验呢?最好是把处理过程中的状态信息即时反馈给用户,就像杀毒软件扫描文件的时候,把扫描结果即时显示出来。

HttpResponse  位于命名空间:  System.Web

HttpResponse 类的方法和属性通过 HttpApplicationHttpContextPageUserControl类的Response属性公开。

HttpResponse 类的方法 Write将信息写入 HTTP 应输出流。

HttpResponse 类的方法 Flush用来向客户端强制发送当前所有缓冲的输出数据,在请求处理期间,允许多次调用该方法。改方法仅仅在回发的情况(不包括异步回发情况)下才被支持。

我们可以利用Response.Flush方法来实现上述设想。

下面用一个示例来演示如何实时提示处理过程的状态。出于演示的目的,将不考虑具体的业务。

在网站项目里,新建一个Web窗体Default.aspx

窗体上放置一个Button控件,给Button控件添加Click处理事件。我们将单击这个Button来触发传说中的大数据量的超复杂的业务运算。

再往窗体上添加一个<iframe>元素:

<iframe src="Output.aspx" id="OutputFrame" allowtransparency="true" frameborder="1"

    width="400px" height="200px" scrolling="auto" marginheight="0"></iframe>

 

注意<iframe>src属性的值是“Output.aspx”。再追加一个新的Web窗体,名为“Output.aspx”,通过请求它在<iframe>来显示处理结果。

删除Output.aspx页面上的所有自动生成的html代码。在Page_Load事件里添加处理过程,处理那个传说中的大数据量的超复杂的业务运算。并且在这个处理过程中,实时地用Response.Write方法输出当前处理的状态信息,并且用Response.Flush强制回发给客户端,使用户得到及时的反馈。

代码很简单,很容易理解,注意两点:


1、在
Default.aspxButtonClick事件处理过程中,定义一个Session,存储一个标识和其他画面输入的数据,用于传递到Output.aspx页面,在Output.aspx页面上判断,只有该Session存在,并且标识正确的情况下,才使用Session保存的其他信息,来做那个传说中的大数据量的超复杂的业务运算;

2:在每次输出信息的时候,同时输出一行脚本,控制着<iframe>的的垂直滚动条滚动到最底下,让用户不用拖动滚动条就可以看到最新的输出信息。

 

全部的代码如下:

Default.aspx


<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

    private const string SessionKey 
= "Default";

    protected 
void Button1_Click(object sender, EventArgs e)
    
{
        Hashtable ht 
= new Hashtable();
        ht.Add(
"post""true");
        ht.Add(
"count", TextBox1.Text);
        Session[SessionKey] 
= ht;
    }

</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    
<title>Demo - HttpResponse.Flush 方法</title>
</head>
<body>
    
<form id="form1" runat="server">
        
<asp:ScriptManager ID="ScriptManager1" runat="server" />
        
<div>
            
<asp:Label ID="Label1" runat="server" Text="Label">实行次数</asp:Label>
            
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
            
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="实行" />
            
<br />
            
<iframe src="Output.aspx" id="OutputFrame" allowtransparency="true" frameborder="1"
                width
="400px" height="200px" scrolling="auto" marginheight="0"></iframe>
        
</div>
    
</form>
</body>
</html>


Output.aspx

 


<%@ Page Language="C#" %>

<script runat="server">
    private const string SessionKey 
= "Default";

    protected void Page_Load(object sender, EventArgs e)
    {
        string startHTML 
= "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" + Environment.NewLine
            + "<html xmlns=\"http://www.w3.org/1999/xhtml\" >" + Environment.NewLine
            + "<head>" + Environment.NewLine
            
+ "</head>" + Environment.NewLine
            
+ "<body>" + Environment.NewLine;

        startHTML += new String(' '1024+ Environment.NewLine;

        Response.Write(startHTML);
        Response.Flush();

        if (Session[SessionKey] != null)
        {
            Hashtable ht 
= (Hashtable)Session[SessionKey];
            Session[SessionKey] 
= null;

            Output(ht);
        }

        string endhTML = Environment.NewLine + "</body>" + Environment.NewLine
            
+ "</html>";

        Response.Write(endhTML);
        Response.Flush();
    }

    private void Output(Hashtable ht)
    {
        
if (ht.ContainsKey("post"&& ht["post"].ToString() == "true")
        {
            string js 
= "<script type=\"text/javascript\">window.scrollTo(0, document.body.scrollHeight);<" + "/script>";
            int count = 0;
            int.TryParse(ht[
"count"].ToString(), out count);

            Response.Write("开始<br/>");
            Response.Flush();

            for (int i = 0; i < count; i++)
            {
                Response.Write(string.Format(
"正在处理第<span style='color:blue'>&nbsp;{0}&nbsp;</span>次……", i + 1));
                Response.Write(js);
                Response.Flush();

                System.Threading.Thread.Sleep(1 * 1000);

                Response.Write("<span style='color:red'>完成</span><br/>");
                Response.Flush();
            }

            Response.Write("结束<br/>");
            Response.Write(js);
            Response.Flush();
        }
    }
</script>

 演示结果截图


转自:http://www.cnblogs.com/Philoo/archive/2009/09/10/1564266.html

抱歉!评论已关闭.