5,666,547 members and growing! (14,912 online)
Email Password   helpLost your password?
Web Development » ASP.NET » General     Intermediate License: The Code Project Open License (CPOL)

Another Simple Wait Page

By Hardy Wang

An article to demonstrate to use asynchronous delegate call and client script callback to build long wait page
Javascript, XML, C# 2.0, C#, Windows, .NET, .NET 2.0, ASP.NET, Ajax, VS2005, Visual Studio, Dev

Posted: 11 Oct 2006
Updated: 11 Oct 2006
Views: 28,175
Bookmarked: 44 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
5 votes for this Article.
Popularity: 3.10 Rating: 4.43 out of 5
0 votes, 0.0%
1
0 votes, 0.0%
2
0 votes, 0.0%
3
2 votes, 40.0%
4
3 votes, 60.0%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article

Sample Image - screenshot.jpg

Introduction

Sometime you need to process a lengthy job in your web form. It is a better idea to build a wait page instead of letting your user just stare at the screen doing nothing.

Background

There are a lot of solutions over Internet to accomplish this purpose. My solution isn't new, the initial idea is from Brian Dunnington's article Building a Better Wait Page in code project. I have been using this approach for long time in ASP.NET 1.1. Since the release of ASP.NET 2.0, Microsoft makes a lot easier to implement client side callback, I decided to expand this solution to include AJAX function, so that we don't need to refresh the page from time to time.

Using the code

There are 3 main areas you need to consider in this solution

  • Asynchronous delegate call
  • Hook up with client callback
  • Client script

Asynchronous delegate call

    /// <summary>

    /// Definition of delegate

    /// </summary>

    /// <param name="minute"></param>

    /// <returns></returns>

    private delegate bool DoJobDelegate (int minute);

    /// <summary>

    /// To invoke the long process function

    /// </summary>

    /// <param name="minute"></param>

    /// <returns></returns>

    private IAsyncResult DoJobAsync(int minute) {
        DoJobDelegate doDelegate = new DoJobDelegate(doLongJob);
        IAsyncResult ar = doDelegate.BeginInvoke(minute, 
                          new AsyncCallback(MyCallback), null);
        return ar;
    }

    /// <summary>

    /// The server side callback handler

    /// </summary>

    /// <param name="ar"></param>

    private void MyCallback (IAsyncResult ar) {
        AsyncResult aResult = (AsyncResult)ar;
        DoJobDelegate doDelegate = (DoJobDelegate)aResult.AsyncDelegate;
        // Session object is used to tell if process finishes or not

        Session["NewOrderResult"] = doDelegate.EndInvoke(ar);
    }

    /// <summary>

    /// The main function to run long process

    /// </summary>

    /// <param name="minute"></param>

    /// <returns></returns>

    private bool doLongJob (int minute) {
        System.Threading.Thread.Sleep(minute * 1000 * 60);
        if (minute % 2 == 0) {
            return true;
        } else {
            return false;
        }
    }

Hook up with client callback

In order to hook with client callback, you have to implement ICallbackEventHandler interface

public partial class Process : System.Web.UI.Page, ICallbackEventHandler {
 protected string CallBackEventReference;
...
}

Then we need to prepare script to reference client function

        string ScriptRef = this.ClientScript.GetCallbackEventReference(
        this,
        "'CheckStatus'",
        "ClientCallBack",
        "this",
        "ClientCallBack",
        true);

        CallBackEventReference = ScriptRef;

This will create a client function like WebForm_DoCallback('__Page','CheckStatus',ClientCallBack,this,ClientCallBack,true);

From this point, you need to implement 2 functions of this interface

    /// <summary>

    /// Capture the event argument in this field, in this case I don't use it.

    /// </summary>

    string eventArgument = "";

    /// <summary>

    /// Returns result to client side

    /// </summary>

    /// <returns></returns>

    string ICallbackEventHandler.GetCallbackResult() {
        if (Session["NewOrderResult"] != null) {
            // after async call finishes,

            // it sets this Session object to some value,

            // this method will capture the status

            if (Convert.ToBoolean(Session["NewOrderResult"])) {
                return "even.htm";
            } else {
                return "odd.htm";
            }
        } else {
            return "";
        }
    }

    /// <summary>

    /// Gets parameter passed from client side

    /// </summary>

    /// <param name="eventArgument"></param>

    void ICallbackEventHandler.RaiseCallbackEvent (string eventArgument) {
        this.eventArgument = eventArgument;
    }

Client script

On the client side, we need to prepare some javascript functions with talk with server.

function ClientCallBack(Result, Context) {
    if (Result != "") {
        window.location.href = Result;
    }
}

In order to make broswer to check server process status, we also need a timer to make client script to run at some certain interval.

<body onload="startClock();">
// check server every 5 seconds, adjust this value to your own preference

var interval = 5
var x = interval
function startClock(){
    x = x - 1;
    setTimeout("startClock()", 1000);
    if(x == 0){
       <%= this.CallBackEventReference %>

So what is happnening now? The client script will be triggered every 5 seconds to talk with server. And ICallbackEventHandler.GetCallbackResult() method on server side will be called every 5 seconds. In this method it checks Session object value, if asynchronous call finishes the process, it will call the MyCallback to set Session object to a not null value returned from process result to make ICallbackEventHandler.GetCallbackResult() be able to capture the result.

Points of Interest

My first explore of client callback, I hope to add more features later.

History

  • 2006-10-11 Initial version.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Hardy Wang



Occupation: Architect
Location: Canada Canada

Other popular ASP.NET articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 14 of 14 (Total in Forum: 14) (Refresh)FirstPrevNext
GeneralIs it possible to use this in a wizardmemberD.Sridhar9:26 5 May '08  
GeneralRe: Is it possible to use this in a wizardmemberHardy Wang9:37 5 May '08  
Generalthe job is load a new pagememberjrmora6:02 7 Mar '08  
GeneralRe: the job is load a new pagememberHardy7:07 7 Mar '08  
QuestionSQL Server Session StatememberSimon Byrne5:37 16 May '07  
AnswerRe: SQL Server Session StatememberHardy4:38 4 Jun '07  
Generalbrowser back buttonmemberJoaquin Luna11:36 9 Dec '06  
GeneralVB.netmemberPapichulo.NET12:04 18 Oct '06  
GeneralRe: VB.netstaffChristian Graus12:39 18 Oct '06  
GeneralRe: VB.netmemberHardy6:15 19 Oct '06  
AnswerRe: VB.netmemberJoaquin Luna12:33 8 Dec '06  
Questionempty source files?memberalex_-_5:42 12 Oct '06  
AnswerRe: empty source files?memberHardy5:46 12 Oct '06  
GeneralThanks !memberdapoussin3:19 12 Oct '06  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 11 Oct 2006
Editor:
Copyright 2006 by Hardy Wang
Everything else Copyright © CodeProject, 1999-2008
Web15 | Advertise on the Code Project