Handling Exceptions Thrown from an Asynchronous Delegate






Handling Exceptions Thrown from an Asynchronous Delegate

Problem

When using a delegate asynchronously, you want to be notified 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 either would simply be discarded and never caught or, if the application had the top, level exception handlers wired up (Recipes 7.10 and 7.20) it would be caught. If EndInvoke is called, then this exception would occur when EndInvoke is called and could be caught there. 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 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 9.4.

For information about wiring up top-level exception handlers in your application, see Recipes 7.10 and 7.20.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows