In certain application cases, asynchronous call is desirable. .NET supports four types of asynchronous call. The following code snippets demonstrate each of the four types. The complete example source code can be downloaded here. Suppose a service takes more than a few seconds to process. The service could be from a local or remote source such as web service. public class BusyTask { public string TestMethod(int callDuration, out int threadId) { threadId = Thread.CurrentThread.ManagedThreadId; Console.WriteLine("Test method in thread {0} begins...", threadId); Thread.Sleep(callDuration); return "MyCallTime was " + callDuration.ToString(); } } Example 1. Use Polling class Program { //the delegate must have the same signature as the method public delegate string BusyTaskAsyncDelegate(int callDuration, out int threadId);
static void Main(string[] args) { int threadId;
//instantiate a BusyTask object BusyTask bt = new BusyTask(); //create the delegate BusyTaskAsyncDelegate dlgt = new BusyTaskAsyncDelegate(bt.TestMethod);
//initiate the asynchronous call IAsyncResult ar = dlgt.BeginInvoke(5000, out threadId, null, null);
//main thread doing sth while polling while (!ar.IsCompleted) { Console.WriteLine("Main thread {0} is doing sth...", Thread.CurrentThread.ManagedThreadId); Thread.Sleep(1000); }
//Call EndInvoke to retrieve the results string ret = dlgt.EndInvoke(out threadId, ar);
Console.WriteLine("The call executed on thread with ID {0} returned value \"{1}\".", threadId, ret); Console.WriteLine("Completed asynchronously? {0}", ar.CompletedSynchronously ? "No" : "Yes"); } } Example 2. Use WaitHandle class Program { //the delegate must have the same signature as the method public delegate string BusyTaskAsyncDelegate(int callDuration, out int threadId);
static void Main(string[] args) { int threadId;
//instantiate a BusyTask object BusyTask bt = new BusyTask(); //create the delegate BusyTaskAsyncDelegate dlgt = new BusyTaskAsyncDelegate(bt.TestMethod);
//initiate the asynchronous call IAsyncResult ar = dlgt.BeginInvoke(5000, out threadId, null, null);
//main thread doing sth Thread.Sleep(1000); Console.WriteLine("Main thread {0} did some work.", Thread.CurrentThread.ManagedThreadId);
//wait for WaitHandle to become signaled ar.AsyncWaitHandle.WaitOne();
//perform some additional work here Console.WriteLine("WaitHandle completed.");
//Call EndInvoke to retrieve the results string ret = dlgt.EndInvoke(out threadId, ar);
Console.WriteLine("The call executed on thread with ID {0} returned value \"{1}\".", threadId, ret); Console.WriteLine("Completed asynchronously? {0}", ar.CompletedSynchronously ? "No" : "Yes"); } } Example 3. Use EndInvoke class Program { //the delegate must have the same signature as the method public delegate string BusyTaskAsyncDelegate(int callDuration, out int threadId);
static void Main(string[] args) { int threadId;
//instantiate a BusyTask object BusyTask bt = new BusyTask();
//create the delegate BusyTaskAsyncDelegate dlgt = new BusyTaskAsyncDelegate(bt.TestMethod);
//initiate the asynchronous call IAsyncResult ar = dlgt.BeginInvoke(5000, out threadId, null, null);
//main thread doing sth Thread.Sleep(1000); Console.WriteLine("Main thread {0} did some work.", Thread.CurrentThread.ManagedThreadId);
//call EndInvoke to wait for the asynchronous call to complete //and receive the result string ret = dlgt.EndInvoke(out threadId, ar);
Console.WriteLine("The call executed on thread with ID {0} returned value \"{1}\".", threadId, ret); Console.WriteLine("Completed asynchronously? {0}", ar.CompletedSynchronously ? "No" : "Yes"); } } Example 4. Use Callback class Program { //the delegate must have the same signature as the method public delegate string BusyTaskAsyncDelegate(int callDuration, out int threadId);
//Asynchronous method puts the thread ID here static int threadId; static bool callbackDone = false;
static void Main(string[] args) { //instantiate a BusyTask object BusyTask bt = new BusyTask(); //create the delegate BusyTaskAsyncDelegate dlgt = new BusyTaskAsyncDelegate(bt.TestMethod);
//initiate the asynchronous call, //passing in AsyncCallback delegate //representing the callback method //and the data needed to call EndInvoke IAsyncResult ar = dlgt.BeginInvoke( 5000, out threadId, new AsyncCallback(CallbackMethod), dlgt); //main thread doing sth while (!callbackDone) { Console.WriteLine("Main thread {0} is doing some work...", Thread.CurrentThread.ManagedThreadId); Thread.Sleep(1000); } }
//callback method must have the same signature //as the AsyncCallback delegate static void CallbackMethod( IAsyncResult ar ) { //retrieve the delegate BusyTaskAsyncDelegate dlgt = (BusyTaskAsyncDelegate)ar.AsyncState;
//call EndInvoke to retrieve the results string ret = dlgt.EndInvoke(out threadId, ar); Console.WriteLine("The call executed on thread with ID {0} returned value \"{1}\".", threadId, ret); Console.WriteLine("Completed asynchronously? {0}", ar.CompletedSynchronously ? "No" : "Yes"); callbackDone = true; } } |