16.3 Asynchronous Delegates

Sometimes it is desirable to call a method asynchronously, so the call returns immediately while the method executes on a separate thread. The runtime provides a standard way that any method can be called asynchronously, taking into account retrieving return values and ref/in parameters supplied to the method. When the C# compiler encounters a delegate, the delegate derived class it generates contains three key methods :

 return-type Invoke (parameter-list); IAsyncResult BeginInvoke (parameter-list, AsyncCallback ac, object state); return-type EndInvoke (ref/out-only parameter-list, IAsyncCallback ac); 

Calling Invoke( ) calls the method synchronously, and the caller has to wait until the delegate finishes executing (a standard delegate invocation in C# calls Invoke( ) ).

Calling BeginInvoke( ) invokes the delegate with the supplied parameter list, then immediately returns. This asynchronous call is performed as soon as a thread is available in the ThreadPool. Two additional parameters are added to BeginInvoke( ) : an AsyncCallback object, to optionally specify a delegate to execute by the ThreadPool thread just before it returns, and an arbitrary object to hold state. The AsyncCallback delegate signature is a void method with a single IAsyncResult parameter, which lets you access information about the call.

Calling EndInvoke( ) retrieves the return value of the called method, along with any ref/out parameters that may have been modified.

In the following example, we call TimeConsumingFunction( ) twice asynchronously, whereby the Main method can continue executing while work is being done by each TimeConsumingFunction . To keep the example simple, these functions happen to execute very fast, but this methodology could be applied to much slower functions such as file I/O functions.

 using System; using System.Threading; using System.Runtime.Remoting.Messaging;    delegate int Compute (string s);    public class Test {   static int TimeConsumingFunction (string s) {     return s.Length;   }      static void DisplayFunctionResult (IAsyncResult ar) {     Compute c = (Compute)((AsyncResult)ar).AsyncDelegate;     int result = c.EndInvoke(ar);     string s = (string)ar.AsyncState;     Console.WriteLine ("{0} is {1} characters long", s, result);   }      static void Main ( ) {     Compute c = new Compute (TimeConsumingFunction);     AsyncCallback ac = new AsyncCallback (DisplayFunctionResult);     string s1 = "Christopher";     string s2 = "Nolan";     IAsyncResult ar1 = c.BeginInvoke (s1, ac, s1);     IAsyncResult ar2 = c.BeginInvoke (s2, ac, s2);     Console.WriteLine ("Ready");     Console.Read( );   } } 

The output is:

 Ready Christopher is 11 characters long Nolan is 5 characters long 


C# in a Nutshell
C # in a Nutshell, Second Edition
ISBN: 0596005261
EAN: 2147483647
Year: 2005
Pages: 963

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net