Help! Retrieve Results from Asynchronous Executions

R

r1

I am relatively inexperienced in using delegates and asynchronous
methods. I read several articles, and then I developed my own code
with a mission to improve the performance. Wow! I cannot believe the
difference in speed! However, the asynch operation fails sometimes,
despite of the fact that it works most of the time. I am really at a
loss how to fix this sporadic and erratic behavior.

This is a web application developed with Visual Studio 2003 (.NET
framework 1.1). The following C# code snippet shows that I use two
delegates to provide a built-in way to call two mainframe DB2 stored
procedures, SPX and SPY. I need to execute SPX and SPY many times,
each time passing different parameters as per signature of the method.
This code is in the server-side Business Logic layer (behind an ASP.NET
page to service a client request of a long running report).

With those asynch methods shown in the example, the code compiles and
runs incredibly fast when compared to the old-fashioned way of making
one call at a time. I was very happy with the performance and the
results from the asynch executions were correct.

However, I came across a really peculiar and sporadic error from
mscorlib.dll with an error message "object reference not set to an
instance of an object". This error is totally incomprehensible to
me. Here are the symptoms: (1) It seems to me the error only occurred
sporadically or randomly (because the application runs fine most of the
time). (2) Whenever the error occurred, the call stack pointed to one
of the many EndInvoke statements (not necessarily a particular
EndInvoke statement, but randomly one of the many EndInvoke
statements).

I apologize for putting down so much writing and code snippet. I
sincerely hope someone can shed some light on this mysterious error.
Any help or suggestion is greatly appreciated!

Code Snippet:

public delegate string SPXCaller(int Division);
public delegate string[] SPYCaller(int TimePeriod, int CategoryType,
int Division);

public class AsyncMethods
{
public AsyncMethods()
{
}

public string ExecSPX(int Division)
{
//This method contains code to exec DB2 stored procedure SPX
//SPX returns 1 output parameter as string
}
public string[] ExecSPY(int TimePeriod, int CategoryType, int
Division)
{
//This method contains code to exec DB2 stored procedure SPY
//SPY returns 5 output parameters as string[5]
}
}

public class BusinessData
{
public DataSet GetData()
{
//Declares a new DataSet to hold all data
DataSet dsData = new DataSet();

//Initiate the Asynchronous calls to exec SPX
AsyncMethods Task1 = new AsyncMethods();
SPXCaller Task1Caller = new SPXCaller(Task1.ExecSPX);
IAsyncResult Result1 = Task1Caller.BeginInvoke(8,null,null);

AsyncMethods Task2 = new AsyncMethods();
SPXCaller Task2Caller = new SPXCaller(Task2.ExecSPX);
IAsyncResult Result2 = Task2Caller.BeginInvoke(10,null,null);

//Initiate the Asynchronous calls to exec SPY
AsyncMethods Task11T = new AsyncMethods();
SPYCaller Task11TCaller = new SPYCaller(Task11T.ExecSPY);
IAsyncResult Result11T = Task11TCaller.BeginInvoke(1,1,8,null,null);

AsyncMethods Task12T = new AsyncMethods();
SPYCaller Task12TCaller = new SPYCaller(Task12T.ExecSPY);
IAsyncResult Result12T = Task12TCaller.BeginInvoke(1,2,8,null,null);

AsyncMethods Task11M = new AsyncMethods();
SPYCaller Task11MCaller = new SPYCaller(Task11M.ExecSPY);
IAsyncResult Result11M =
Task11MCaller.BeginInvoke(1,1,10,null,null);

AsyncMethods Task12M = new AsyncMethods();
SPYCaller Task12MCaller = new SPYCaller(Task12M.ExecSPY);
IAsyncResult Result12M =
Task12MCaller.BeginInvoke(1,2,10,null,null);

AsyncMethods Task21T = new AsyncMethods();
SPYCaller Task21TCaller = new SPYCaller(Task21T.ExecSPY);
IAsyncResult Result21T = Task21TCaller.BeginInvoke(2,1,8,null,null);

AsyncMethods Task22T = new AsyncMethods();
SPYCaller Task22TCaller = new SPYCaller(Task22T.ExecSPY);
IAsyncResult Result22T = Task22TCaller.BeginInvoke(2,2,8,null,null);

AsyncMethods Task23T = new AsyncMethods();
SPYCaller Task23TCaller = new SPYCaller(Task23T.ExecSPY);
IAsyncResult Result23T = Task23TCaller.BeginInvoke(2,3,8,null,null);

AsyncMethods Task21M = new AsyncMethods();
SPYCaller Task21MCaller = new SPYCaller(Task21M.ExecSPY);
IAsyncResult Result21M =
Task21MCaller.BeginInvoke(2,1,10,null,null);

AsyncMethods Task22M = new AsyncMethods();
SPYCaller Task22MCaller = new SPYCaller(Task22M.ExecSPY);
IAsyncResult Result22M =
Task22MCaller.BeginInvoke(2,2,10,null,null);

AsyncMethods Task23M = new AsyncMethods();
SPYCaller Task23MCaller = new SPYCaller(Task23M.ExecSPY);
IAsyncResult Result23M =
Task23MCaller.BeginInvoke(2,3,10,null,null);

//All calls to BeginInvoke return right away.
//We can immediately move on to do another task.
//The following independent, long running task retrieves PO data
//while waiting for all asynch executions (DB2 store proc) to
finish.
DataTable dtPOData = GetPOData();

//Now, retrieve the return values by calling the EndInvoke method.
//Retrieve results from SPXCaller
string Ret1 = Task1Caller.EndInvoke(Result1);
string Ret2 = Task2Caller.EndInvoke(Result2);

//Retrieve results from SPYCaller
string[] Ret11T = Task11TCaller.EndInvoke(Result11T);
string[] Ret12T = Task12TCaller.EndInvoke(Result12T);
string[] Ret11M = Task11MCaller.EndInvoke(Result11M);
string[] Ret12M = Task12MCaller.EndInvoke(Result12M);

string[] Ret21T = Task21TCaller.EndInvoke(Result21T);
string[] Ret22T = Task22TCaller.EndInvoke(Result22T);
string[] Ret23T = Task23TCaller.EndInvoke(Result23T);
string[] Ret21M = Task21MCaller.EndInvoke(Result21M);
string[] Ret22M = Task22MCaller.EndInvoke(Result22M);
string[] Ret23M = Task23MCaller.EndInvoke(Result23M);

//Some source code omitted here. The code packs all results
//into a dataset dsData with multiple datatables.
return dsData;
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top