C# .NET - Asynchronous calls in Asp.Net

Asked By Manisha Chauhan on 07-Jan-09 07:21 AM
Kindly provide some example with code ,how asynchronously methods can be called.
Here is my requirement:-
I m developing a website which requires transaction of inserting lakhs of records in one go.I don;t want that this
transaction blocks in between due to bad network connection or any other reason.

Kindly suggest me some suggestion.What method should i apply to do this so that my taransaction do not interrupt in  any case.  

Calling a method asynchronously

alice johnson replied to Manisha Chauhan on 07-Jan-09 07:48 AM

The following program illustrates the asynchronous call to a WriteSum() method.

Example 1


using System.Threading;
class Program {
   public delegate int Deleg( int a, int b );
   static int WriteSum( int a, int b ) {
      int sum = a + b;
      System.Console.WriteLine( "Thread#{0}: WriteSum() sum = {1}",
             Thread.CurrentThread.ManagedThreadId, sum);
      return sum;
   }
   static void Main() {
      Deleg proc = WriteSum;
      System.IAsyncResult async=proc.BeginInvoke(10,10,null,null);
      // You can do some work here...
      int sum = proc.EndInvoke( async );
      System.Console.WriteLine( "Thread#{0}: Main()   sum = {1}",
             Thread.CurrentThread.ManagedThreadId, sum);
   }
}


This program displays:


Thread 15: WriteSum() Sum = 20
Thread 18: Main()     Sum = 20


An asynchronous call is materialized by an object whose class implements the System.IAsyncResult interface. In this example, the underlying class is System.Runtime.Remoting.Messaging.AsyncResult. The AsyncResult object is returned by the BeginInvoke() method. It is passed as an argument to the EndInvoke() method in order to identify the asynchronous call.

See this link:

http://www.programmersheaven.com/2/Calling-a-method-asynchronously

check this

Santhosh N replied to Manisha Chauhan on 07-Jan-09 11:15 AM
check this link for understanding of this with sample code as well
http://msdn.microsoft.com/en-us/magazine/cc163725.aspx

use beginexecutenonquery and endexecutenonquery

Venkat K replied to Manisha Chauhan on 07-Jan-09 11:21 AM

//method to call the sp

cmd.BeginExecuteNonQuery(callback, cmd);
You can define Callback as:
            AsyncCallback callback = new AsyncCallback(EndAsyncOperation);


You can end the asynchronous process as follows:
   SqlCommand cmdAsyn = (SqlCommand)ar.AsyncState;
            //End the asynchronous call
            cmdAsyn.EndExecuteNonQuery(ar);

Complete example:

IAsyncResult BeginAsyncOperation(object sender, EventArgs e, AsyncCallback cb, object state)
    {
               

        alias = Request.QueryString["ID"].ToString();
        //Added by Venkat FY08 Q4 (v-vekall)
        //TAMTools.Tools.TTService.Cases tts = new TAMTools.Tools.TTService.Cases(gGlob);
        //tts.RefreshCasesForTAM(alias, true);

        Boolean forceClarifyReload = true;
        //SqlConnection conn = gGlob.GetConnection();
        SqlConnection conn = new SqlConnection("Integrated Security=SSPI;Persist Security Info=False;Server=GDCIFAPPSSQL07;Initial Catalog=TamTools;Connection Timeout=0;Asynchronous Processing=true;");
        SqlCommand cmd = new SqlCommand();
        conn.Open();
        cmd.Connection = conn;
        //cmd.CommandTimeout = 0;
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandText = "GetCasesForTAM";

        cmd.Parameters.Add(new SqlParameter("@TAMalias", SqlDbType.VarChar, 100));
        cmd.Parameters.Add(new SqlParameter("@ISForceReload", SqlDbType.Bit, 4));

        if (forceClarifyReload)
        {
            cmd.Parameters["@TAMalias"].Value = alias;
            cmd.Parameters["@ISForceReload"].Value = 1;
        }
        else
        {
            cmd.Parameters["@TAMalias"].Value = alias;
            cmd.Parameters["@ISForceReload"].Value = 0;
        }
        //AsyncCallback callback = new AsyncCallback(EndAsyncOperation);
        return cmd.BeginExecuteNonQuery(cb, state);
       

    }

    void EndAsyncOperation(IAsyncResult ar)
    {
          SqlCommand cmdAsyn = (SqlCommand)ar.AsyncState;
            //End the asynchronous call
            cmdAsyn.EndExecuteNonQuery(ar);

           bindgrid();
    }


read this
C_A P replied to Manisha Chauhan on 08-Jan-09 03:11 AM
there are more than one ways to implement asynchronous calls in asp.net2.0 and you may be asking which pattern to use.

The first way is to use the AddOnPreRenderCompleteAsync

AddOnPreRenderCompleteAsync (
new BeginEventHandler(BeginAsyncMethod),
new EndEventHandler (EndAsyncMethod)
);
The second way is to use the PageAsyncTask and RegisterAsyncTask
PageAsyncTask task = new PageAsyncTask( 
new BeginEventHandler(BeginAsyncMethod),
new EndEventHandler(EndAsyncMethod),
new EndEventHandler(TimeoutAsyncMethod), null
); 
RegisterAsyncTask(task);
 
The second way is preferrably better as it has the following advantages over the first way.
  • RegisterAsyncTask also take an additional parameter for timeout.
  • More than one RegisterAsyncTask can be called in one Request.
  • The fourth parameter of RegisterAsyncTask can take state of the Begin Method.
  • To the End the Timeout Method RegisterAsynTask gives you handy objects (ie HttpContext.Current, impersonation and culture).

Remember to put Async="true" attribute in the @ Page directive for any of the preferred methods mentioned above.

Also for Webservices we can use this following pattern:

theproxy.MyMethodCompleted += new MyMethodCompletedEventHandler (OnMyMethodCompleted);
theproxy.MyMethodAsync (...);
...
void OnMyMethodCompleted (Object source, MyMethodCompletedEventArgs e)
{
// This is called when MyMethod completes
}
For any long running tasks always try to use AsyncMethods as it never ties up threads from the thread pool.
In msdn you will find this great article in this topic: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/Internals.asp. 
try this
C_A P replied to Manisha Chauhan on 08-Jan-09 03:12 AM

Making an Asynchronous Call using the Impersonation Identity

If you try to make an asynchronous call, you will notice that the thread that executes the call doesn't run under the same account as the thread that called it, assuming you are using impersonation.

There are a number of ways to change this if you would like to have it use the same identity.

Method 1

The Thread used by BeginInvoke doesn't copy the windowsIdentity from the calling thread. You have to impersonate the new thread manually:
Before calling BeginInvoke save the current identity into a variable:

Dim identity as WindowsIdentity
identity = System.Security.Principal.WindowsIdentity.GetCurrent()

Inside the asynchronously called method use this variable and execute:

identity.Impersonate

From that point on the asynchronous call uses the same privileges than the calling thread and it should not be a problem to execute the callback.

Method 2

If the thread making the asynchronous call creates the thread being used, and you are using .NET 2.0 or later, you can set the following in the config file.  For ASP.NET, use the aspnet.config file:

<configuration>
<runtime>
<alwaysFlowImpersonationPolicy enabled="true"/>
<legacyImpersonationPolicy enabled="false"/>
</runtime>
</configuration>

Method 3

Another way to handle this is if you have an account that you want the asynchronous call to run under, you can impersonate that account, run what you need to, and then undo the impersonation.  The following code will do that:

using System.Security.Principal;
...
WindowsIdentity wi = new WindowsIdentity(userName@fullyqualifieddomainName);
WindowsImpersonationContext ctx = null;
try
{
ctx = wi.Impersonate();
// Thread is now impersonating
}
catch
{
// Prevent exceptions propagating.
}
try this
C_A P replied to Manisha Chauhan on 08-Jan-09 03:13 AM
check this peter's article at http://www.eggheadcafe.com/articles/20060620.asp