Async Delegates Cheat Sheet

How to use invoke a method asynchronously

1.     Define a delegate

·         Definition must match target method signature.

·         Compiler produces a class containing BeginInvoke and EndInvoke methods

 

delegate int SomeMethodDel(string data)

 

2.     Initialize delegate instance set to target method

 

class MyClass

{

  public void DoSomething()

  {

    SomeMethodDel del = SomeMethod;

  ...

 

3.     Create a completion callback method

·         Callback method signature must match AsyncCallback built-in delegate.

 

class MyClass

{

  void OperationComplete(IAsyncResult ar)

  {

  ...

 

4.     Call BeginInvoke on the delegate instance:
- pass callback method as 2nd to last parameter
- pass delegate instance as the last parameter

 

class MyClass

{

  public void DoSomething()

  {

    SomeMethodDel del = SomeMethod;

    del.BeginInvoke("some data", OperationComplete, del);

  ...

 

5.     In the callback method, get the delegate from the AsyncState property of the IAsyncResult parameter

·         Downcast the AsyncState back to the delegate type.

 

class MyClass

{

  void OperationComplete(IAsyncResult ar)

  {

    SomeMethodDel del = (SomeMethodDel)ar.AsyncState;

  ...

 

6.     Call EndInvoke on the delegate instance

·         Calling EndInvoke allows you to capture the method return value (as well as ref and out parameters).

·         Exceptions thrown in the target method are raised when you call EndInvoke, so you should enclose the call in a try / catch block.

·         Not calling EndInvoke will cause a memory leak unless you explicitly close the AsyncWaitHandle property of IAsyncResult.

 

class MyClass

{

  void OperationComplete(IAsyncResult ar)

  {

    SomeMethodDel del = (SomeMethodDel)ar.AsyncState;

    try

    {

      int result = del.EndInvoke(ar);

    }

    catch (Exception ex)

    { // Perhaps log the exception here }

  ...