Welcome to MSDN Blogs Sign in | Join | Help

How to create a "Loading" page in ASP.NET

Many times we are faced with heavy or slow processing pages in our projects. If we cannot improve performance, how do we display some sort of information in the browser while the page is processing?

I used to have this problem when accessing slow databases or retrieving a large amount of information from it. Sometimes, the queries lasted for 30 seconds or even more and it's not very user-friendly to just sit there waiting. Many impatient users will often assume that the application has hanged and close the browser before the query results are shown.

Let's imagine the following scenario. We have a form where the user specifies some sort of search pattern. He then clicks a button and the results are shown in a datagrid in the same page. Ok, solving this is easy...you just add some client scripting to the button that triggers the round-trip to the database so that on the client side a message will be displayed (something like: please wait...loading the data).

But what if you want to show the results in another aspx? By this I mean you access a page and on the page_load you retrieve the data and populate the datagrid? What if you have a complex form with lots of drop down lists that must be populated and you want to show some sort of info to your users while they are waiting for the page to appear on the browser? And, what if you want to do something like a dynamic bar to show that something is actually happening?

Well, I recently discovered a very useful method of the Response object. Because it functions like a Stream, you are able to say Flush several times during a request. What this means is that you don't have to wait for the entire page to be rendered to send the response down to the client. So, basically this looks like a good way of solving this problem: we create a mixed blend of HTML and JavaScript in the beginning of the Page_Load event, we flush it to the client and we proceed with our server-side processing. When we get the data we don't have to do anything special. The Page_Load event will end and the HTML will be rendered by ASP.NET. All we have to do is possibly hide the information we previously sent in order to display the page correctly.

I encapsulated the entire logic into a single class (C#):

using System;

using System.Web;

namespace WaitPage

{

/// <summary>

/// To use this class, simply insert in the beggining of your page load the following line:

/// Wait.Send_Wait_Info(Response);

///

/// Also, in the HTML part of your web form add the following line at the end of the head section:

/// <script>Stop_Wait();</script>

/// </summary>

public class Wait

{

public Wait()

{

}

const string MAIN_IMAGE = "images/logo.bmp";

const int PROGRESS_BAR_SIZE = 10; //number of steps in your progress bar

const string PROGRESS_BAR_STEP = "images/pro.bmp"; //image for idle steps

const string PROGRESS_BAR_ACTIVE_STEP = "images/pro2.bmp"; //image for active step

 

public static void Send_Wait_Info(System.Web.HttpResponse Response)

{

Response.Write("<div id=\"mydiv\" align=\"center\">");

Response.Write("<img src=\"" + MAIN_IMAGE + "\">");

Response.Write("<div id=\"mydiv2\" align=\"center\">");

for(int i=1;i<=PROGRESS_BAR_SIZE;i++)

{

Response.Write("<img id='pro" + i.ToString() + "' src='" + PROGRESS_BAR_STEP + "'>&nbsp;");

}

Response.Write("</div>");

Response.Write("</div>");

Response.Write("<script language=javascript>");

Response.Write("var counter=1;var countermax = " + PROGRESS_BAR_SIZE + ";function ShowWait()");

Response.Write("{ document.getElementById('pro' + counter).setAttribute(\"src\",\"" + PROGRESS_BAR_ACTIVE_STEP + "\"); if (counter == 1) document.getElementById('pro' + countermax).setAttribute(\"src\",\"" + PROGRESS_BAR_STEP + "\");else {var x=counter - 1; document.getElementById('pro' + x).setAttribute(\"src\",\"" + PROGRESS_BAR_STEP + "\");} counter++;if (counter > countermax) counter=1;}");

Response.Write("function Start_Wait(){mydiv.style.visibility = \"visible\";window.setInterval(\"ShowWait()\",1000);}");

Response.Write("function Stop_Wait(){ mydiv.style.visibility = \"hidden\";window.clearInterval();}");

Response.Write("Start_Wait();</script>");

Response.Flush();

}

}

}

This code will simply send some HTML and Javascript to the client creating an animated progress-like bar. You can download the source code of a demo app showing it's usage here.

The Stop_Wait script block must be inserted in the end of the head section. When the final response is sent, the bar is cleared and the JavaScript cycle that animates the bar is stopped. Pretty simple .

Also, all the images presented can easily be changed. There are 4 constants defined in the class.

  • The main image
  • The size of the bar (how many steps)
  • The image representing a step
  • The image representing the active step

so you can customize this at will. Also, I believe the code will help build your own mechanism. I just did it for the exercise so it's not very pretty :P

Hope this proves of some use to you.

Published Friday, March 12, 2004 11:25 AM by nunos
Filed under:

Comments

Friday, March 12, 2004 12:42 PM by Scott_NO_@_SPAM_Tripleasp.net (Scott Watermasysk)

# RE: How to create a "Loading" page in ASP.NET

Why not just use the body tag's onload attribute?

1. On a postback, Server.Transfer to your "loading page".
2. Pass your long running page either as a querystring parameter or as a value in the context. (sample below uses a querystring)
3. In the body's onload event, set the location.href to your long running page. <body onload="BeginPageLoad()"

function BeginPageLoad() {
location.href = "<%= Request.QueryString["Page"]%>"; }

Once your "long running" page is fully loaded, it should replace your "loading page".

I am pretty sure this example came from ScottGu's black belt tips presentation: http://scottgu.com/BlackBelt_Teched.zip
Friday, March 12, 2004 2:41 PM by Kingsley Tagbo

# re: How to create a "Loading" page in ASP.NET

Very helpful tip. I need to use the technique in several places on my site.
Friday, March 12, 2004 6:09 PM by nunos

# re: How to create a "Loading" page in ASP.NET

Well...I didn't actually believe I was doing something new here. I discussed this a bit with other ASP.NET developers inside MS and someone eventually mentioned the Response.Flush and we came up with this.

The approach your suggestion also works, and it's a good option too. I used this because I wanted to understand exactly how flushing a partial response to the client would work, and provided the Loading page as an example of its usage.

By the way...thanks for the tip...hadn't thought of that :P
Friday, March 12, 2004 9:14 PM by Ole Lytjohan

# re: How to create a "Loading" page in ASP.NET

I have been looking for a solution like that, and did try out yours, i just got a couple disagreements with response.flush it seems + i want a solultion that doesnt require javascript.

#1 if you dont supply enough characters to the output buffer, it wont flush (below 200-300 characters).

#2 the use of javascript, can be easely avoided using css.
Creating a style on the div containing the "preload" text, like
<div style="position:absolute.... but including z-index:-1;">
will make it possible to just overlay your content, and no need for javascript.

#3 it doesnt seem to be working at all in mozilla, but opera likes it as much as ie does.
Friday, March 12, 2004 9:26 PM by Ole Lytjohan

# re: How to create a "Loading" page in ASP.NET

a little addon for my former post.
you dont even have to overlay it offcourse, you can just give the loading container an ID like <div id="foobar"> loading .... </div>

and on the loaded content include a style #foobar { display:none; }

that works wonders :)
Friday, March 19, 2004 1:10 PM by Bob.Yexley.Blog

# DailyBytes.Add(

Tuesday, March 23, 2004 7:18 PM by Ash

# re: How to create a "Loading" page in ASP.NET

I used ur code but it takes while before it is loaded ..i am calling it in Page_Load event ...also if you upload the BMP images it wud be great ;)

Thanks for the code --Kool.
Ash.
Wednesday, March 24, 2004 10:32 AM by nunos

# re: How to create a "Loading" page in ASP.NET

Hi Ash. I did upload the images.

"You can download the source code of a demo app showing it's usage here." ('here' is actually a hyperlink though it isn't very clear).

http://vs.tkolegacy.org/samples/Wait.zip

Hope it helps
Thursday, March 25, 2004 11:17 PM by Jenny Kalinina

# re: How to create a "Loading" page in ASP.NET

Hi,

I try to use this code, it works well, but there is a problem here. It is flushing well while processing my page and then returns to my page if ererything is okay. But if any error happens while processing I redirect to error page, and have amessage I have the message "Cannot redirect after HTTP headers have been sent."
What could I do with that?

Thanks
Friday, March 26, 2004 11:13 AM by nunos

# re: How to create a "Loading" page in ASP.NET

Jenny: you can do that in a simple way. Add a hidden html input field to your page. I called it error_control. Right click on it and choose Run as Server Control.
If you catch an error, instead of redirecting in code do this:

error_control.value = "error"

Change the data.aspx page (at the end of the head section):

<script>Stop_Wait();

function test_error()
{
var error_value = document.getElementById("error_control").getAttribute("value");
if (error_value = "error") document.location.href="error.aspx";
}

</script>

and on the body tag include onload="test_error();"

When the page_load event finishes, the page gets loaded and the test_error function will run. If you set the value of the error_control in a catch block, the page will be redirected to your error page.

Optionally, if you want to know what error you encountered on the error page, you can insert in the error_control the Exception type or message and change the test_error message like this:

function test_error()
{
var error_value = document.getElementById("error_control").getAttribute("value");
if (error_value != "") document.location.href="error.aspx?error=" + error_value;
}

Hope this helps
Friday, March 26, 2004 3:57 PM by Jenny Kalinina

# re: How to create a "Loading" page in ASP.NET

Thanks, it helps. But I have one more question (sorry, I am a beginer):
After the page is redirected to my error page, I cannot go back to my original page using Back optin of Internat Explorer. Should close and run application again which is not good...
How could I fix that?

Thanks
Friday, March 26, 2004 4:58 PM by nunos

# re: How to create a "Loading" page in ASP.NET

Jenny: that's because the page gets cached on the client and when you do back it will automatically redirect you back to the error page again.

Now it all depends on what you want to do when the user clicks back. If you want to try the request again, you can do the following:

In the first line of Page_Load event insert this piece of code:

Response.AppendHeader("Cache-Control","no-cache,must-revalidate");

That will force the browser NOT to cache the page, so when you click back the request will be attempted again (and possibly generate the error again...depends on the type of error).

Alternative, you can also pass to the error page (as a parameter) some url that sould be used to start over. With this info you can populate a link on the error page so that the user gets redirected to some "start again" page (maybe the home page).

And feel free to ask as many questions you like (or need). After all this is what blogging is all about.

Cheers
Monday, March 29, 2004 7:11 PM by Jenny Kalinina

# re: How to create a "Loading" page in ASP.NET

Thanks a lot.. It's great that there is such place to get quick help.

Monday, April 05, 2004 3:09 AM by Jenny Kalinina

# re: How to create a "Loading" page in ASP.NET

Hi,

Could you please help with one more problem:

I have a few buttons on my page b1, b2, b3. Each of them does processing of information.
Buttons b1 and b2 process data very fast and I do not want to display waiting page. But for b3
waiting page should be displayed. So I run Wait.Send_Wait_Info(Response) in b3_click (not in page_load). Then when I click menu to open my page or click others buttons on my page, I get run time error ‘Object expected’, because it tries to execute Stop_Wait which doesn’t exist. How could I get rid of that error?

Thanks in advance
Thursday, April 22, 2004 12:36 PM by .Pablo: Mi Blog de .NET

# C

Thursday, April 29, 2004 4:31 PM by Bob.Yexley.Blog

# DailyBytes.Add(

Monday, May 31, 2004 4:06 PM by Alla Staroseletskaya

# re: How to create a "Loading" page in ASP.NET

I wanted to downloaded zip file from your site. It's not there. Could you provide it?

I will appreciate your effort.

Alla
Monday, May 31, 2004 11:55 PM by Alla Staroseletskaya

# re: How to create a "Loading" page in ASP.NET

Wait.Send_Wait_Info(Response); I t does not work for me. Please help.
Please upload bmp images. Where is you zip-file?

Alla
Friday, June 04, 2004 7:49 PM by ccc

# re: How to create a "Loading" page in ASP.NET

ccc
Thursday, July 01, 2004 9:28 AM by MacFly

# re: How to create a "Loading" page in ASP.NET

Just a little tip
You can type

Response.Write("function Stop_Wait(){ mydiv.style.display = \"none\";window.clearInterval();}");

instead of

Response.Write("function Stop_Wait(){ mydiv.style.visibility = \"hidden\";window.clearInterval();}");

so your page will be refreshed correctly (the "div" section isn't displayed any more. With "visibility=hidden", the div section is displayed but not visible, so it takes some place in tour page).

Thanks Nunos for your code, I thought I will never find a working example of a "Loading page".
Monday, July 26, 2004 6:02 AM by Jack

# re: How to create a "Loading" page in ASP.NET

Can you please provide a zipped file for he sample code, to test, as the one on the blog does not open up
Monday, July 26, 2004 12:15 PM by nunos

# re: How to create a "Loading" page in ASP.NET

I'm sorry guys for the missing zip file. I had in a server that went down.
I'll try and find an alternate location to it. Or you can just email me and request it.

BTW, I'll have to build the sample again....I formatted my machine recently so I don't have it. I'll try to be quick about it.
Wednesday, July 28, 2004 12:00 AM by everett

# re: How to create a "Loading" page in ASP.NET

Nunos,
Great code, thanks!!! Don't know your email address, but could you send the zip file to mine? everettwolf@sbcglobal.net

Thanks!!!!
Wednesday, July 28, 2004 10:48 AM by nunos

# re: How to create a "Loading" page in ASP.NET

Oops...sorry about that...my email is nunos@microsoft.com
Wednesday, July 28, 2004 9:34 PM by everett

# re: How to create a "Loading" page in ASP.NET

One tiny enhancement:

re:
/// Also, in the HTML part of your web form add the following line at the end of the head section:

/// <script>Stop_Wait();</script>
end re:

You can actually put this in the Send_Wait_Info() function right after Response.Flush(); like this:
...
Response.Flush()
Response.Write("<script>Stop_Wait();</script>");
...

It won't get written until the page loads, so it works out to be the same thing as putting it in the <HEAD> tag of the HTML.

This way, all your code is in one place and you can plop the whole thing in a shared class and not have to worry about explaining this part..... (At least, this works in IE 6)

Thanks, nunos, for the code. It's a big help.
Wednesday, August 04, 2004 6:22 AM by Nancy W.

# re: How to create a "Loading" page in ASP.NET

I used very similar code in my app - all codes are in Page_Load directly. At first it worked. Later somehow I got "Server cannot clear headers after HTTP headers have been sent.". I suspect this is caused by "window.clearInterval". Does anybody get the same error?

nunos, can you send me the zip file of your code? My email address is wwwfamily@excite.com. Thank you very much!
Friday, April 15, 2005 2:26 AM by LYNCH

# MY NOTEBOOK

Monday, November 26, 2007 2:04 AM by How to create a "Loading" page in ASP.NET

# How to create a "Loading" page in ASP.NET

Friday, November 14, 2008 4:41 AM by Buspar.

# Buspar manufacturer.

Buspar experience. Buspar side effects. Buspar anxiety. Buspar.

Anonymous comments are disabled
 
Page view tracker