Click here to Skip to main content
Licence CPOL
First Posted 2 Apr 2008
Views 14,396
Downloads 77
Bookmarked 25 times

Asynchronous Processing

By | 2 Apr 2008 | Article
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:

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:

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:

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:

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:

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:

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)

About the Author

Emeka Awagu

Software Developer

Nigeria Nigeria

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionAsynchronous processing Pinmemberstixoffire13:01 8 Apr '08  
I am just curious what kind of web application / request would require/benefit from asynchronous processing. Do you have an example (a simple explanation of it would do for me.).
 
Just a small hint here - you have written an article and jumped right into the code. Explaining the task - purposes / benefits / drawbacks / issues would have been a nice introduction to help me understand the article better.
Thank you for posting.
GeneralRe: Asynchronous processing Pinmemberfodaley13:07 8 Apr '08  
GeneralNeeds a Project PinmemberDewey15:52 3 Apr '08  
GeneralRe: Needs a Project PinmemberEmeka Awagu1:29 4 Apr '08  
GeneralRe: Needs a Project Pinmemberosmofrilander20:59 8 Apr '08  
GeneralRe: Needs a Project PinmemberYves7:35 7 Apr '09  

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

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120604.1 | Last Updated 3 Apr 2008
Article Copyright 2008 by Emeka Awagu
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid