|
|
Recipe 5.17 Handling Exceptions Thrown from an Asynchronous DelegateProblemWhen using a delegate asynchronously, you want to be notified in the calling thread if the delegate has thrown any exceptions. SolutionWrap 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
}
}
DiscussionIf 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 AlsoFor more on calling delegates asynchronously, see Recipe 7.4. |
|
|