Asynchronous page processing

Asked By Arjit Malviya
30-Jul-10 05:59 AM
Earn up to 0 extra points for answering this tough question.

I am working on 3 tier architecture: UI, BL, DAL. In my UI i have following code for Asynchronous page processing:

AddOnPreRenderCompleteAsync(new BeginEventHandler(objAsync_BL.BeginAsyncWork1), new EndEventHandler(objAsync_BL.EndAsyncWork1));

objAsync_BL.BeginAsyncWork1 and objAsync_BL.EndAsyncWork1 are functions in BL and the call the functions objAsync_DL.BeginAsyncWork1 objAsync_DL.EndAsyncWork1 of DAL.

Now i am colleceting an output parameter of type string in EndAsyncWork1 of DAL and i want to return thisstring to UI. But the problem is that EndAsyncWork1 has return type void; below is the defination of both the functions:

      public IAsyncResult BeginAsyncWork1(Object sender, EventArgs e, AsyncCallback cb, object state)
      {
        open();
        op = new SqlParameter("@Result", SqlDbType.VarChar, 50);
        op.Direction = ParameterDirection.Output;

        cmd = new SqlCommand("fs_check", con);
        cmd.CommandType = CommandType.StoredProcedure;

        SqlParameter pm1 = new SqlParameter();
        pm1 = new SqlParameter("@email_id", "abcd");

        cmd.Parameters.Add(pm1);
        cmd.Parameters.Add(op);     

        return cmd.BeginExecuteReader(cb, state);

      }

      public void EndAsyncWork1(IAsyncResult asyncResult)
      {
        string _emailIdFS = null;

        cmd.EndExecuteNonQuery(asyncResult);
        _emailIdFS = op.Value.ToString();
        
        return _emailIdFS;
      }

When I am changing the return type of EndAsyncWork1 to string, I am getting the following error: (changed in both BL, and DAL)

Error    1    'string BusinessLayer.Async_BL.EndAsyncWork1(System.IAsyncResult)' has the wrong return type

----------------------------------------------------------------------------------------------

Also BeginAsyncWork1 accepts following parameter

(Object sender, EventArgs e, AsyncCallback cb, object state)

I want to pass one more string type to this function like (Object sender, EventArgs e, AsyncCallback cb, object state, string s)

but it is giving error that "No overload for 'BeginAsyncWork1' matches delegate 'System.Web.BeginEventHandler' "

  re: Asynchronous page processing

Peter Bromberg replied to Arjit Malviya
30-Jul-10 09:28 AM
Pass your custom data in the State parameter. You cannot change the signatured for the APM methods. You can cast it back to your custom type from the asyncResult object in the callback.

  re: Asynchronous page processing

Arjit Malviya replied to Peter Bromberg
30-Jul-10 09:47 AM
Thanx Peter for your reply. Can you elaborate this with an example?.

  re: Asynchronous page processing

Peter Bromberg replied to Arjit Malviya
30-Jul-10 09:56 AM
You can see an example in this article:   http://www.eggheadcafe.com/tutorials/aspnet/10697ee3-bc13-4ca4-9443-988bfcbaaacc/build-a-multiprovider-as.aspx

Create a custom class with whatever fields you need to convey and pass it into the object state parameter.

In the callback method, the  asyncResult.AsyncState field will hold this object.
  re: Asynchronous page processing
Arjit Malviya replied to Peter Bromberg
30-Jul-10 10:19 AM
Gone through your example. Can you look in this highlighted problem?
"Now i am colleceting an output parameter of type string in EndAsyncWork1 of DAL and i want to return thisstring to UI. But the problem is that EndAsyncWork1 has return type void;"

I want to send back this string to BL from DAL and then from BL to UI
  re: Asynchronous page processing
Peter Bromberg replied to Arjit Malviya
30-Jul-10 10:34 AM
protected void UpdateUI()
{
// your logic here to pass the string to your calling class
}

MethodInvoker updaterMI = new MethodInvoker(UpdateUI);
this.BeginInvoke(updaterMI);
  re: Asynchronous page processing
Arjit Malviya replied to Peter Bromberg
30-Jul-10 01:45 PM
Thanks peter for replying again. I am unable to solve my problem, i am expecting a brief explanation. What I am trying to do is mentioned below:

I am working on 3 tier architecture: UI, BL, DAL. In my UI i have following code for Asynchronous page processing:
protected void Page_Load(object sender, EventArgs e) 
{  
   AddOnPreRenderCompleteAsync(new BeginEventHandler(objAsync_BL.BeginAsyncWork1), new EndEventHandler(objAsync_BL.EndAsyncWork1)); 
 
 public IAsyncResult BeginAsyncWork1(Object sender, EventArgs e, AsyncCallback cb, object state) 
 {     
 
 
 
 public void EndAsyncWork1(IAsyncResult asyncResult) 
 
 
 


But I want a database fetch operation to be performed in this asyncronous method. And due to 3 tier arch. i am unable to do this in UI Layer. Please guide me that how can I implement Asynchronous processing in 3 tier architecture?

Note: If you are going to place EndAsyncWork1 in DAL then please show that how can I return a value back to UI layer from this function.

  re: Asynchronous page processing
Peter Bromberg replied to Arjit Malviya
30-Jul-10 01:52 PM
I don't know how your DAL is constructed.

protected void Page_Load(object sender, EventArgs e) 
{  
   AddOnPreRenderCompleteAsync(new BeginEventHandler(objAsync_BL.BeginAsyncWork1), new EndEventHandler(objAsync_BL.EndAsyncWork1)); 
 
 public IAsyncResult BeginAsyncWork1(Object sender, EventArgs e, AsyncCallback cb, object state) 
 {   
   Dal dal = new Dal();
    dal.SubmitUnitOfWork( stateObject);
    // you can pass the entire dal instance as the State object if you want
 
 
 public void EndAsyncWork1(IAsyncResult asyncResult) 
 
    Dal dal= (Dal) asyncResult.AsyncState;
  // get the returned data and
    // update the UI here.
 
 
  re: Asynchronous page processing
Arjit Malviya replied to Peter Bromberg
30-Jul-10 03:31 PM
Ok so I have read your post and I have implemented the following, please tell me that is it right or not.

UI:
protected void Page_Load(object sender, EventArgs e)
AddOnPreRenderCompleteAsync(new BeginEventHandler(BeginAsyncWork1), new EndEventHandler(EndAsyncWork1));
}
 
IAsyncResult BeginAsyncWork1(Object sender, EventArgs e, AsyncCallback cb, object state)
   {
  Async_BL objAsync_BL = new Async_BL();
  objAsync_BL.bl(_emailId, state);
   }
 
  void EndAsyncWork1(IAsyncResult asyncResult)
  {
  string[] _dataGProfile = new string[11];

  Async_BL objAsync_BL = (Async_BL)asyncResult.AsyncState;

      // What to do here, i am not sure.

  _dataGProfile = objAsync_BL.bl(_emailId, state);
  }

BL:

public string[] bl(string _emailId, object state)
  {
  Async_DL objAsync_DL = new Async_DL();
  return objAsync_DL.getFsDL(_emailId);
  }

DAL:
public string[] getFsDL(string _emailId)
  {
  string[] _dataGProfile = new string[11];
 
  open();
  SqlParameter op = new SqlParameter("@Result", SqlDbType.VarChar, 50);
  op.Direction = ParameterDirection.Output;
 
  SqlCommand cmd = new SqlCommand("fs_check", con);
  cmd.CommandType = CommandType.StoredProcedure;
 
  SqlParameter pm1 = new SqlParameter();
  pm1 = new SqlParameter("@email_id", _emailId);
 
  cmd.Parameters.Add(pm1);
  cmd.Parameters.Add(op);
 
  try
  {
  cmd.ExecuteNonQuery();
  _emailId = op.Value.ToString();
  close();
 
  FetchData_DL objFetchData_DL = new FetchData_DL();
  _dataGProfile = objFetchData_DL.getGProfile(_emailId);
  }
  catch (Exception ex)
  {
  logger.Error(ex);
  }
  finally
  {
  cmd.Dispose();
  close();
  }

  return _dataGProfile;

 }



Is i am receiving return value right in EndAsyncWork1 ?
  re: Asynchronous page processing
Arjit Malviya replied to Peter Bromberg
30-Jul-10 05:06 PM
Hi Peter,
My problem is solved. Thanks to you, your hints helped me a lot :)
Create New Account