Click here to Skip to main content
15,899,754 members
Articles / Web Development / ASP.NET

Asynchronous Processing

Rate me:
Please Sign up or sign in to vote.
3.43/5 (11 votes)
2 Apr 2008CPOL1 min read 33.3K   226   28   6
An easier way to asynchronously process web page requests.

Introduction

The idea of asynchronous processing in ASP.NET has always been very appealing. However, I found it a bit tedious to use and wanted a more manageable way to use asynchronous processing everywhere on my website. I wanted to centralize the way I performed these calls throughout my application. So, I created a class which I called AsynchronousProcessingManager.

Using the code

The AsynchronousProcessingManager looks like this:

C#
public class AsynchronousProcessingManager
{
    //fields
    AsynchronousTaskDelegate methodDelegate;
    public event AsyncProcessingEndedEventHandler OnAsyncProcessingEnded;

    //constructor
    public AsynchronousProcessingManager(AsynchronousTaskDelegate atd)
    {
        this.methodDelegate = atd;
    }

    public IAsyncResult BeginAsyncTask(object sender, 
        EventArgs e, AsyncCallback ac, object state)
    {
        IAsyncResult result =
           this.methodDelegate.BeginInvoke(ac, state);
        return result;
    }

    public void EndAsyncTask(IAsyncResult result)
    {
        AsynchronousTaskDelegate cd =
           (AsynchronousTaskDelegate)((AsyncResult)result).AsyncDelegate;
        AsyncResultObject aro = cd.EndInvoke(result);
        if (OnAsyncProcessingEnded != null)
        {
            AsyncEndedEventArgs ae = new AsyncEndedEventArgs(aro);
            OnAsyncProcessingEnded(this, ae);
        }
        this.methodDelegate = null;
        cd = null;
    }

    public void AsyncCallBack(IAsyncResult result)
    {
        // AsynchronousProcessingManager apm =
        // (AsynchronousProcessingManager)result.AsyncState;
    }
}

The Begin and End AsyncTasks are necessary for the ASP.NET PageAsyncTask class. In the EndAsyncTask, I fire an event of type AsyncProcessingEndedEventHandler which contains an object of type AsyncResultObject. The AsynchronousProcessingManager also has a field, 'methodDelegate', of type AsynchronousTaskDelegate, which will hold a reference to the method to be called. The 'methodDelegate' returns an AsyncResultObject which is contained in the AsyncEndedEventArgs:

C#
public delegate AsyncResultObject AsynchronousTaskDelegate();
public delegate void AsyncProcessingEndedEventHandler(object sender,
       AsyncEndedEventArgs ae);

public class AsyncEndedEventArgs
{
    AsyncResultObject resultObject;

    public AsyncEndedEventArgs(AsyncResultObject rObject)
    {
        this.resultObject = rObject;
    }

    public AsyncResultObject ResultObject
    {
        get { return this.resultObject; }
        set { this.resultObject = value; }
    }
}

Within the body of the method, I instantiate an AsynchronousProcessingManager with a constructor that takes the AsynchronousTaskDelegate. I then wire the OnAsyncProcessingEnded event to a method supplied as one of the parameters. This is the method that will be called after the the async processing has finished. I then call ASP.NET's RegisterAsyncTask for the current page that is passed as a parameter as well.

As an example, I have a page called default.aspx. I want to call a method that performs a long running query in a database. I define the method as follows:

C#
private AsyncResultObject DoQuery()
{
    AsyncResultObject aro = new AsyncResultObject();
    try
    {
        //query
        aro.ResultObject = //result of query
    }
    catch(Exception e)
    {
        aro.Exception = e;
    }
    return aro;
}

I also define the method to be called at the end of the async processing:

C#
private void DoQueryEnded(object sender, AsyncEndedEventArgs ae)
{
    AsyncResultObject aro = ae.ResultObject;
    if(aro.Exception != null)
    {
        //handle the exception
    }
    else
    {
        //do something with the aro.ResultObject
    }
}

I also have a Timeout method:

C#
private void TimeOut(IAsyncResult ar)
{
    Response.Write("Try again later");
    //or something along those lines
}

To call the method from the page, I simply write:

C#
ProcessAsyncTask(new AsynchronousTaskDelegate(DoQuery),
      new AsyncProcessingEndedEventHandler(DoQueryEnded),
      new EndedEventHandler(TimeOut), this);

I use this model throughout my application and it seems to work fine...so far!

License

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


Written By
Software Developer
Nigeria Nigeria
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionAsynchronous processing Pin
stixoffire8-Apr-08 13:01
stixoffire8-Apr-08 13:01 
GeneralRe: Asynchronous processing Pin
fodaley8-Apr-08 13:07
fodaley8-Apr-08 13:07 
I didn't look at this article in detail, but, I use asynchronous processes to send e-mails for web apps. Instead of having the user sit there and wait for the connection to the mail server, for the e-mail to be sent, etc...my process is async. The send e-mail function gets called. The callee moves on and assumes it gets sent. The user goes on their merry way.
GeneralNeeds a Project Pin
Dewey3-Apr-08 15:52
Dewey3-Apr-08 15:52 
GeneralRe: Needs a Project Pin
Emeka Awagu4-Apr-08 1:29
Emeka Awagu4-Apr-08 1:29 
GeneralRe: Needs a Project Pin
oskifree8-Apr-08 20:59
professionaloskifree8-Apr-08 20:59 
GeneralRe: Needs a Project Pin
Yves7-Apr-09 7:35
Yves7-Apr-09 7:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.