5.17. Handling Exceptions Thrown from an Asynchronous Delegate

Problem

When using a delegate asynchronously, you want to be notified in the calling thread if the delegate has thrown any exceptions.

Solution

Wrap the EndInvoke method of the delegate in a try/catch block:

using System;
using System.Threading;

public class AsyncAction
{
    public void PollAsyncDelegate( )
    {
        // Create the async delegate to call Method1 and call its BeginInvoke method
        AsyncInvoke MI = new AsyncInvoke(TestAsyncInvoke.Method1);
        IAsyncResult AR = MI.BeginInvoke(null, null);

        // Poll until the async delegate is finished
        while (!AR.IsCompleted)
        {
            System.Threading.Thread.Sleep(100);
            Console.Write('.'),
        }
        Console.WriteLine("Finished Polling");

        // Call the EndInvoke method of the async delegate
        try
               {
               int RetVal = MI.EndInvoke(AR);
               Console.WriteLine("RetVal: " + RetVal);
               }
               catch (Exception e)
               {
               Console.WriteLine(e.ToString( ));
               }
    }
}

The following code defines the AsyncInvoke delegate and the asynchronously invoked static method TestAsyncInvoke.Method1:

public delegate int AsyncInvoke( );

public class TestAsyncInvoke
{
    public static int Method1( )
    {
        throw (new Exception("Method1"));    // Simulate an exception being thrown
    }
}

Discussion

If the code in the PollAsyncDelegate method did not contain a call to the delegate’s EndInvoke method, the exception thrown in Method1 would simply be discarded and never caught. This behavior is by design; for all unhandled exceptions that occur within the thread, the thread immediately returns to the thread pool and the exception is lost.

If a method that was called asynchronously through a delegate throws an exception, the only way to trap that exception object is to include a call to the delegate’s EndInvoke method and wrap this call in an exception handler. The EndInvoke method must be called to retrieve the results of the asynchronous delegate; in fact, the EndInvoke method must be called even if there are no results. These results can be obtained through a return value or any ref or out parameters of the delegate.

See Also

For more on calling delegates asynchronously, see Recipe 7.4.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.71.28