ASP.NET - Asynchronous page processing

Asked By Arjit Malviya
30-Jul-10 05:59 AM

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' "

  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.
  Arjit Malviya replied to Peter Bromberg
30-Jul-10 09:47 AM
Thanx Peter for your reply. Can you elaborate this with an example?.
  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.
  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
  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);
  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.

  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.
 
 
  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 ?
  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
help
controls are created and data is provided. . . . but if users select less text box then error occurs that " no. of rows specified or columns specified does not match". . . . . . . . . . HOPE you all Unit6, @Rate6, @Amt6, @DiscAmt, @StAmt, @VatAmt, @AVatAmt, @NetTotal)", con); cmd4.Parameters.Add(new SqlParameter("@Name", SqlDbType.VarChar)); cmd4.Parameters.Add(new SqlParameter("@Address", SqlDbType.VarChar)); cmd4.Parameters.Add(new SqlParameter("@VNo", SqlDbType.Int)); cmd4.Parameters.Add(new SqlParameter("@VDate", SqlDbType.DateTime)); cmd4.Parameters.Add(new SqlParameter("@BillNo SqlDbType.Int)); cmd4.Parameters.Add(new SqlParameter("@Remark", SqlDbType.VarChar)); cmd4.Parameters.Add(new SqlParameter("@ItemName1", SqlDbType.VarChar)); cmd4.Parameters.Add(new SqlParameter("@Qty1", SqlDbType.Float)); cmd4.Parameters.Add(new SqlParameter("@Pcs1
Error Handling in a called function Hi Guys, A quick question for you. I have a Sub which calls a Function several times. Both the Sub & Function have error handling. The problem is, when there is an error in the called Function, the calling Sub Error Handler fires. How can I get the Function Error Handler to fire? Cheers Pete You can return a boolean from the Function to indicate whther it was successful. For example: Private Sub SendTrades() On Error GoTo Err_Handler 'do some stuff If EmailTrades(parameters) Then 'Do more stuff. . . . Else MsgBox "Problem Description Resume Err_Resume End Sub Public Function EmailTrades(ByVal parameters as blah) As Boolean On Error GoTo Err_Handler 'do some emailing stuff. If it fails here, the function will return false will help you. Hi Vickey, Thanks for the speedy reply. In the function where the error occurs, I don't want it to return a boolean and exit. There is other
will help you Hi I am getting the following message at the time of compilation Error 52 The install location for prerequisites has not been set to 'component vendor's web framework files in the Application folder of setup project ? But I am getting the following error messages when compiling the setup project Error 1 The install location for prerequisites has not been set to 'component vendor's web on disk. See Help for more information. H: \ SOURCES \ IMPEX SETUP \ IMPEXSETUP \ IMPEXSETUP.vdproj IMPEXSETUP Error 2 The install location for prerequisites has not been set to 'component vendor's web on disk. See Help for more information. H: \ SOURCES \ IMPEX SETUP \ IMPEXSETUP \ IMPEXSETUP.vdproj IMPEXSETUP Error 3 The install location for prerequisites has not been set to 'component vendor's web on disk. See Help for more information. H: \ SOURCES \ IMPEX SETUP \ IMPEXSETUP \ IMPEXSETUP.vdproj IMPEXSETUP Error 4 The install location for prerequisites has not been set to 'component vendor's web on disk. See Help for more information. H: \ SOURCES \ IMPEX SETUP \ IMPEXSETUP \ IMPEXSETUP.vdproj IMPEXSETUP Error 5 The install location for prerequisites has not been set to 'component vendor's web on disk. See Help for more information. H: \ SOURCES \ IMPEX SETUP \ IMPEXSETUP \ IMPEXSETUP.vdproj IMPEXSETUP Error 6 The install location for prerequisites has not been set to 'component vendor's web
Web config error message When I try to open up a dotnetnuke site I get this error message: Configuration Error Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately. Parser Error Message: Unrecognized configuration section 'connectionStrings' Source Error: Line 15: < / sectionGroup> Line 16: < / configSections> Line 17: <connectionStrings> Line 18: <!- - Connection String for SQL disk but can neither access it or save data on it. I added it same error message: Configuration Error Description: An error occurred during the processing of a configuration file required