in

ASP.NET Weblogs

-[Danny Chen]- Blog of an ASP.NET QA tester

Tips and info about Site Navigation, ImageMap, Menu and other cool ASP.NET v2.0 features.

A custom control challenge - make a page loading control that just works.

It is a fairly well known technique to use Response.Buffer and Response.Flush to make a "please wait" or "Loading..." message appear when you know a page is going to take a while to load.  So I was quite estatic when I read on ScottGu's blog that someone (Daniel Fisher) had done what I've wanted to do for a while: formalize this trick into a nice tidy custom control you can just drop onto a page.  You can see it here:  http://www.lennybacon.com/PleaseWaitBuildingAWaitScreenControlForASPNET.aspx.  It is really a very slick control.  However, there was one problem I couldn't (and still can't) figure out which stopped me from writing this control initially.  When I look more closely at Daniel's code, I noticed that he hadn't solved this problem either.

The problem

How do you write the control so that it doesn't wrap a specific function but instead works against the natural page loading time itself.  Here's a scenario to help describe what I mean.  Lets say you develop a page with a couple GridView's and DetailsViews bound to SqlDataSource's.  Everything works great in your mock up but as soon as you deploy it against your live data, you find that the page takes 2-8 seconds to load.  It would be awesome if you could simple take this "loading ..." control, drop it onto your page and -bang- the functionality is added.  Now, I know there's an easy solution using Daniels code and simple adding the DataBinding logic into his OnProcess method, but that's not the point.  This should be a drag-and-drop solution.

The challenge

Create a custom control that provides similar functionality to Daniels but works against the page processing time.  A "drag and drop" kind of solution.  If you think you can do something that even I can't figure out how to do, please contact me through my blog and I will get back to you over email.  I'll post the best submissions I receive and declare the submitters to be "Elite ASP.NET Hackers"

 

Comments

 

Bertrand Le Roy said:

Bonus points for not clogging the thread pool with the long-running process by having a background process handle it while the web server does what it's best at: serving wait page that just poll the background process until it's done, at which time it can render the final page... Which is exactly what the asynchronous process application block is doing IIRC.
A much better solution, but considerably more complex to set up.
Daniel's control is very well fit for cases where performance and stress are not an issue (intranets and low-frequentation sites).
February 24, 2006 4:51 PM
 

Michael Teper said:

I havent tried this, but wouldn't something like this work?

OnInit, send the "Loading" div,
OnPreRender, send code to clear the div.
February 28, 2006 2:51 AM
 

Wouter van Vugt said:

Anyone realizes that this might be very hard to do without ackward code? Viewing a part in the browser implies the Render phase, databinding and such usually happen during Load / Change / Click. When you then try to render, controls such as a DataGrid will break due to it already being the Render phase.

My 2 cents. Please correct me if I'm wrong :)

I did implement it though: http://blogs.infosupport.com/wouterv/archive/2006/03/01/4013.aspx
March 1, 2006 8:23 AM
 

Danny Chen said:

Michael Teper,
Probably something like that would work on the page but not necessarily in a control because you can't garentee the order these calls would be made in the controls (except that the page is always last). Databinding happens in PreRender and is likely to be where a lot of processing takes place.
March 1, 2006 1:16 PM
 

Danny Chen said:

Wouter,
Yes, most of the solutions I've seen (both submitted from this "challenge" and otherwise have some awkward code.

Some of them also produce random error messages related to Session state because of the Response.Flush() calls.

However, there have been some crafty solutions. I'll try and post the best ones I've received so far either today or tomorrow.
March 1, 2006 1:20 PM
 

Robert McKee said:

OnInit:
If headers does not contain "no-wait":
If no cache object exists:
Dump and flush the wait div.
Create a WebClient and call itself with an added header of "no-wait".
Store the result in cache for later retrieval.
Dump a javascript block to redirect back to itself again.
response.end
ELSE
Dump the cache object to the browser (including any headers/cookies).
response.end
endif
endif

You may run into some minor issues regarding sessions, but those can be worked around within the control.
March 3, 2006 12:13 PM
 

Danny Chen said:

Hi Robert,
That sounds like yet another solution that I haven't seen. It would be great if you could convert that into a working sample I could post for other users to see!
--
Danny
March 3, 2006 1:03 PM
 

Francisco Lomas said:

Hey guys I have tested the control replacing the handler with OnProcess="Page_Load" and it works fine to beat the challege, if you like on out of the box solution only configure the OnProcess with the Page_Load event by default...

September 18, 2007 8:12 PM

Leave a Comment

(required)  
(optional)
(required)  
Add