如果Server端处理Client端的响应需要的时间太长,这时候给用户显示另一个界面来告知用户示服务器正在处理,请用户稍等,这样显然更友好一些!
解决这个需求貌似有个现成的解决方案, ASP.NET AJAX有个控件叫UpdateProgress, 用法可以参见这里。但是这个UpdateProgress有个缺点,就是它会自动对它所关联的UpdatePanel里面的所有控件(Button),也是就是它的粒度是UpdatePanel级别的,而不是具体某个控件级别的。当然,可以把要关联的控件单独放在一个UpdatePanel里面,但是这显然很不灵活。而且,UpdateProgress不会把当前的界面隐藏,而只是在当前页面的基础之上“增加”了一些显示服务器正在处理,请稍后的信息。这个不符合我想要的结果---当服务器端响应客户端请求的时候隐藏当前界面,显示一个中间结果,当请求响应完毕的时候再显示原来的界面。
还有另外两个貌似可以解决的方案,一个运用Asynchronous Delegate来处理比较耗时的请求,让当前的Postback很快返回给客户端。但是这种方法最大的困难在于,当Server端处理完这个请求的时候怎么通知页面来更新状态。因为Web Application不同于Desktop Application,当页面请求完成之后,当前的页面的所有对象都被destroy了。
另外一个是注意到“Async Page”,但是这个ASP.NET提供的Feature与我的需求相去甚远, Async Page的意思是当Server端响应一个比较耗时的页面请求时候,会从Thread Pool中取出一个thread来处理这个耗时的请求,这样不至于使得所有的客户端的请求都hog一个很长时间的thread,不利于很多页面请求的web site.
回归到解决这个问题本身,其实解决方法也很直观,当页面PostBack的时候,用Javascript隐藏当前的界面,显示中间界面即可。
举个例子:
ASPX页面代码:
这个页面很简单,就是一个TextBox模拟用户请求状态, 这个TextBox放在一个DIV (ID = “ChangeTextDiv”)里面,这个DIV默认是可见的。
另外一个DIV(ID=”IntermediatePageDiv“),顾名思义,这个DIV是在服务端响应客户请求是显示的中间界面。
控制这两个DIV的显示和消失,自然是通过Javascript来动态设置它们的class (style).
注意Button (BtnPostBack )同时注册了两个事件处理函数,
OnClick="BtnPostBack_Click" OnClientClick="ChangeStyle();"
1: <html xmlns="http://www.w3.org/1999/xhtml" >
2: <head runat="server">
3: <title>Untitled Page</title>
4: <link href="App_Themes/Stylesheet1.css" rel="stylesheet" type="text/css" />
5: <script type="text/javascript">
1:
2: function ChangeStyle()
3: {
4: var div1 = document.getElementById("ChangeTextDiv");
5: div1.className="NoDisplay";
6:
7: var div2 = document.getElementById("IntermediatePageDiv");
8: div2.className="";
9: }
10:
</
script
>
6:
7: </head>
8: <body>
9: <form id="form1" runat="server">
10:
11: <asp:Button Text="Request" ID="BtnPostBack" OnClick="BtnPostBack_Click" OnClientClick="ChangeStyle();" runat="server" />
12:
13: <div id="ChangeTextDiv">
14: <asp:TextBox ID="TbChangeText" Text="Change Me" runat="server"></asp:TextBox>
15: </div>
16:
17: <div id="IntermediatePageDiv" class="NoDisplay">
18: Please wait while processing the request...
19: </div>
20:
21: </form>
22: </body>
23: </html>
CSS:
1: .NoDisplay
2: {
3: display:none
4: }
CS 代码很简单,用Thread.Sleep(2000)来模拟比较耗时的页面请求处理,
1: protected void BtnPostBack_Click(object theSender, EventArgs theEventArgs)
2: {
3: Thread.Sleep(2000);
4: TbChangeText.Text = "Complete your request!";
5: }
That's It!
相关界面显示如下:
-- The End--
<<<< 续>>>
可以设置DIV的样式,使得每次显示提示信息的时候显示在页面的中央位置....
<div id="IntermediatePageDiv" class="NoDisplay" style="border:solid 1px Black; width:200px; height:200px;
margin:auto auto"> Please wait while processing the request...
</div>