Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: WCF Asynchronous
I have one web page MyWebPage.aspx which while loading has to show data from two webservices along with it's own algorithm.
 
1) WebServiceI.SomeMethod() -> Takes 10 seconds aprx. to respond.
2) WebServiceII.SomeMethod() -> Takes 10 seconds aprx. to respond.
3) My Algorithm -> Takes 5 second aprx to respond.
Now,when I call this synchronously,this will take 10+10+5 = 25 seconds to load.
 
So,I was suggested "Asynchronous Calling Method",i.e. using IAsyncResult/AsyncCallback. Now what will(should) happen is that all will be called simultaneously and the page will load in max 10 seconds.
 
So I call them now in the "Begin/End" way...
 
public partial class MyWebPage : System.Web.UI.Page
{
      WebServiceI WebServiceIObject = new WebServiceI();
      WebServiceII WebServiceIIObject = new WebServiceII();
 
protected void Page_Load(object sender, EventArgs e)
{
      //BeginSomeMethod(AsyncCallback callback, object asyncState)[<- Method Signature]
      WebServiceIObject.BeginSomeMethod(OnEndGetWebServiceISomeMethodResult, null);
 

      //BeginSomeMethod(AsyncCallback callback, object asyncState)[<- Method Signature]
      WebServiceIIObject.BeginSomeMethod(OnEndGetWebServiceIISomeMethodResult, null);
 

/* My Algorithm 5 seconds*/
DataSet DS = GetDataSetFromSomeWhere();
MyGataGrid.DataSource = DS.tables[0];
MyGataGrid.DataBind();
/* My Algorithm 5 seconds*/
 

//System.Threading.Thread.Sleep(6000);
}
 
//Will be called after 10 seconds
void OnEndGetWebServiceISomeMethodResult(IAsyncResult asyncResult)
{
string WebServiceISomeMethodResult = WebServiceIObject.EndSomeMethod(asyncResult);
MyLabelI.Text = WebServiceISomeMethodResult;
//EventLog MyLog = new EventLog("Application"); MyLog.Source = "MySourceI";
//MyLog.WriteEntry(DateTime.Now.ToString());
}
 
//Will be called after 10 seconds
void OnEndGetWebServiceIISomeMethodResult(IAsyncResult asyncResult)
{
string WebServiceIISomeMethodResult = WebServiceIIObject.EndSomeMethod(asyncResult);
MyLabelII.Text = WebServiceIISomeMethodResult;
//EventLog MyLog = new EventLog("Application"); MyLog.Source = "MySourceII";
//MyLog.WriteEntry(DateTime.Now.ToString());
}
}
Now the issue with the above example is that MyLabelI & MyLabelII Text are never set because the page loads after 5 seconds
 
and thread is released.Both End Methods are called correctly as checked by writing to EventLog. How can I resolve this... something like "All start at once and then all wait till all are complete..." I understand that if my executing thread waits for 5 seconds more then the code executes as required..
 
How should I use AsyncWaitHandle...
 
Or is it simply not possible from server side coding??
Posted 30-Nov-11 19:51pm

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Well,The answer to this problem is "System.Web.UI.PageAsyncTask" class.It allows Asynchronous calls to tasks and waits for completion on the same thread.Also multiple tasks can be created and made to run parallel.Please go through the documentation for further information...Will work in Asp.Net 2.0 & Above Only.
For our problem above...I am putting "My Algorithm" as sync and both other tasks as Async parallel.So my page will take 10+5 = 15 seconds to load.
 
      public partial class MyWebPage : System.Web.UI.Page
      {
      WebServiceI WebServiceIObject = new WebServiceI();
      WebServiceII WebServiceIIObject = new WebServiceII();
     
      protected void Page_Load(object sender, EventArgs e)
      {
      PageAsyncTask PAT_I = new PageAsyncTask
      (BeginGetWebServiceISomeMethodResult, OnEndGetWebServiceISomeMethodResult, null, null, true);
      Page.RegisterAsyncTask(PAT_I);
      PageAsyncTask PAT_II = new PageAsyncTask
      (BeginGetWebServiceIISomeMethodResult, OnEndGetWebServiceIISomeMethodResult, null, null, true);
      Page.RegisterAsyncTask(PAT_II);
      Page.ExecuteRegisteredAsyncTasks();
     
      /* My Algorithm 5 seconds*/
      DataSet DS = GetDataSetFromSomeWhere();
      MyGataGrid.DataSource = DS.tables[0];
      MyGataGrid.DataBind();
      /* My Algorithm 5 seconds*/
      }
      IAsyncResult BeginGetWebServiceISomeMethodResult
          (object Sender, EventArgs EventArgsObject,
          AsyncCallback AsyncCallbackObject, object PassAnythingExtraIfRequired)
      {
            return WebServiceIObject.BeginSomeMethod(AsyncCallbackObject, PassAnythingExtraIfRequired);
      }

      IAsyncResult BeginGetWebServiceIISomeMethodResult
          (object Sender, EventArgs EventArgsObject,
          AsyncCallback AsyncCallbackObject, object PassAnythingExtraIfRequired)
      {
            return WebServiceIIObject.BeginSomeMethod(AsyncCallbackObject, PassAnythingExtraIfRequired);
      }
        
      void OnEndGetWebServiceISomeMethodResult(IAsyncResult asyncResult)
      {
      string WebServiceISomeMethodResult = WebServiceIObject.EndSomeMethod(asyncResult);
      MyLabelI.Text = WebServiceISomeMethodResult;
      }
      void OnEndGetWebServiceIISomeMethodResult(IAsyncResult asyncResult)
      {
      string WebServiceIISomeMethodResult = WebServiceIIObject.EndSomeMethod(asyncResult);
      MyLabelII.Text = WebServiceIISomeMethodResult;
      }
      }
Works Smile | :) The code can be made generic with common refactoring...
Please be careful while planning for this kind of design though...Internally this must also be using threads from threadpool only...I have not dug in deep..but must be..So if the tasks happen to take moretime than planned and if several such tasks get raised at the same time,then web server could suffer and users could get time out...
I am still carrying this forward inspite of above flaw as my users will time out anyway if 25 seconds turns out to be 55 seconds...Better to have a situation where some users are able to work rather than none..
If there is some better alternative,please post.
  Permalink  

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

  Print Answers RSS
0 Sergey Alexandrovich Kryukov 474
1 Maciej Los 390
2 OriginalGriff 318
3 CHill60 205
4 CPallini 179
0 OriginalGriff 6,152
1 Sergey Alexandrovich Kryukov 5,312
2 Maciej Los 3,279
3 Peter Leow 3,184
4 DamithSL 2,490


Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 1 Dec 2011
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100