Retrieving Results from Asynchronous Delegates


When you execute a delegate asynchronously, control returns to the application immediately, before the delegate is done executing the function. Because the delegate hasn't completed, output parameters aren't yet known. Therefore you have to wait until the delegate is done executing to retrieve the output values. The delegate class provides a function called EndInvoke to retrieve output values. There are two ways of using EndInvoke depending on how you called BeginInvoke : writing code that waits, or providing a callback function.

To retrieve output parameters if you have code that waits for the delegates to finish:

  1. If you invoked the delegates asynchronously and waited for the delegates to complete, you most likely have delegate variables such as del1 and del2, and IAsyncResult variables such as ar1 and ar2.

  2. Type object result = del1.EndInvoke(ar1, outparam1, outparam2); where result is any variable to accept the result value. The type of result is shown as object, but it can be the specific type that the delegate function returns; ar1 is the name of the variable holding the IAsyncResult value returned from the call to BeginInvoke ; outparam1 and outparam2 are variables for each ref or out parameter specified in the delegate function ( Figure 10.20 ).

    Figure 10.20 Because the functions begin execution and return immediately, there's no way of knowing the return parameters on the BeginInvoke. You need to wait until they're done and then call EndInvoke to get the return values.
     class Tasks {    public bool Task1(string desc)    {       return true;    }    public static bool Task2(string desc)    {       return true;    } } delegate bool TaskDel(string desc); public class WebForm1 : System.Web.UI.Page {    private void Page_Load(object sender,                 System.EventArgs e)    {       Tasks tsks = new Tasks();       TaskDel del1 =       new TaskDel(tsks.Task1);       TaskDel del2 =       new TaskDel(Tasks.Task2);       IAsyncResult ar1 =       del1.BeginInvoke(       "Calling Task1...",null,null);       IAsyncResult ar2 =       del2.BeginInvoke(       "Calling Task2...",null,null);       System.Threading.WaitHandle[]       handles =       new System.Threading.WaitHandle[]       {ar1.AsyncWaitHandle ,       ar2.AsyncWaitHandle };       System.Threading.WaitHandle.       WaitAll(handles,2000,false);  bool retval1 = del1.EndInvoke(ar1);   bool retval2 = del2.EndInvoke(ar2);  } } 

To retrieve output parameters if you have a callback function:

The trick to remember when using a callback function is that you don't have the original delegate variable when the callback function executes. But you can retrieve it from the parameter of the callback function.

  1. Type DelegateTypeName del1 = (DelegateTypeName) ((System.Runtime.Remoting.Messaging.AsyncResult)ar). AsyncDelegate ; where del is any variable to hold the delegate object, and ar is the name of the input parameter.

  2. Follow step 2 from the previous section to retrieve the output parameters with EndInvoke ( Figure 10.21 ).

    Figure 10.21 In the case of the system telling us when it's done executing the functions, we may not have the original delegate variables and we need them to call EndInvoke and retrieve the output parameters. Luckily, the system gives us the original delegate variable through the AsyncResult parameter.
     class Tasks {    public bool Task1(string desc)    {       return true;    }    public static bool Task2(string desc)    {       return true;    } } delegate bool TaskDel(string desc);  public class WebForm1 :   System.Web.UI.Page   {   public void FunctionDone (   IAsyncResult ar)   {   TaskDel del1 = (TaskDel)   ((System.Runtime.Remoting.   Messaging.AsyncResult)ar).   AsyncDelegate;   bool result = del1.EndInvoke(ar);   }  private void Page_Load(object sender,                 System.EventArgs e)    {       Tasks tsks = new Tasks();       TaskDel del1 =       new TaskDel(tsks.Task1);       TaskDel del2 =       new TaskDel(Tasks.Task2);  AsyncCallback cb = new   AsyncCallback(this.FunctionDone);  IAsyncResult ar1 =       del1.BeginInvoke(       "Calling Task1...",  cb  ,null);       IAsyncResult ar2 =       del2.BeginInvoke(       "Calling Task2...",  cb  ,null);    } } 

graphics/tick.gif Tips

  • EndInvoke can be used to retrieve the output parameter of the function, plus any ref or out parameters of the delegate function.

  • Every delegate object has a BeginInvoke function and an EndInvoke function as well as the Invoke function, which is used for synchronous operation. Other classes mimic this behavior: They provide a BeginInvoke/EndInvoke for asynchronous operations and an Invoke function for synchronous operations. For example, the class WebClient also uses the same pattern for asynchronous vs. synchronous operation.




C#
C# & VB.NET Conversion Pocket Reference
ISBN: 0596003196
EAN: 2147483647
Year: 2003
Pages: 198
Authors: Jose Mojica

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