When using a delegate asynchronously, you want to be notified in the calling thread if the delegate has thrown any exceptions.
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 } }
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.
For more on calling delegates asynchronously, see Recipe 7.4.
3.22.71.28