|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
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
IntroductionThe 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 using asynchronous processing everywhere on my websites. I wanted to centralise the way i performed these calls thoughout my application. I created a class which i called AsynchronousProcessingManager. Using the code
The
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, this 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 the 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 retrieves 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
}
So 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!
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||