# Wednesday, 18 March 2009
« Speaking at DevWeek 09 | Main | A Tale of Two Reader/Writer Locks »

The .NET Async pattern is a very neat way of running functionality asynchronously. The async pattern is where for a synchronous method DoWork be have a pair of methods BeginDoWork and EndDoWork to handle running the DoWork functionality on the threadpool. Now it is well documented that if I call the Begin method I must also call the End method to allow the async infrastructure to clean up resources it may have acquired. However, where do I call the End version?

Consider async delegate invocation. Quite often I’d like to just fire off the async method and forget about it but I have to call EndInvoke. Fortunately lambdas make this really easy

Action a = DoWork;
a.BeginInvoke( ar => a.EndInvoke(ar) );

Now there is a nasty problem. What happens if DoWork throws an exception? The async delegate infrastructure will conveniently cache the exception and re-throw it when I call EndInvoke. However, the issue is that this is happening in an AsyncCallback delegate on a threadpool thread and so I cannot catch it easily in this construct. Why is that a problem? well since .NET 2.0 an unhandled exception on a background thread will terminate the process. This means to reliably call EndInvoke in an AsyncCallback we must put it in a try … catch. This is annoying code to reliably put in place and is easily forgotten. So I have written an extension method to wrap this functionality for you

public static class Extensions
{
 
public static AsyncCallback Try(this AsyncCallback cb, Action<Exception> exceptionAction)
 
{
   
AsyncCallback wrapper = delegate(IAsyncResult iar)
    {
     
try
     
{
       
cb(iar);
     
}
     
catch (Exception e)
     
{
       
exceptionAction(e);
     
}
   
};
   
return wrapper;
  }
}

So this code extends AsyncCallback and takes a delegate to call if an exception takes place it then wraps its own AsyncCallback around the one passed in this time putting it in a try … catch block. The usage looks like this:

Action a = DoStuff;
AsyncCallback cb = ia => a.EndInvoke(ia);
a.BeginInvoke(cb.Try(e => Console.WriteLine(e)), null);

The only awkward thing here is having to take the lambda out of the call to BeginInvoke because the C# compiler won’t allow the dot operator on a lambda (without casting it to an AsyncCallback) but at least this wraps up some of the issues