Awesomeness Here's a little piece of information you might not know about how ASP.NET 2.0 and above operate. Simply put, if an unhandled exception occurs in a secondary thread which has been launched by your ASP.NET application, IIS will force your application to restart. This can mean lost sessions, bad server side state, slow reloads and, in general, is a bad thing. However, these kinds of exceptions are a pain to discover and resolve if you don't know what you're looking for because the built-in ASP.NET error handler does not get fired and your user is not redirected to an error page, unless something breaks after the web server restarts. (This article explains the cryptic messages you will see in the Event Log).

Here's a simple scenario based on the integration between our interactive kiosk created for The Code Factory co-working space and Twitter. We want our web application to post messages on Twitter when certain events occur (member check-in and member check out). Because we did not want to re-invent the wheel, we found a Twitter C# Library with a permissive software license. Noticing that posting to Twitter slowed down our application and because we didn't want our application to depend on Twitter's availability, we decided to run this code asynchronously. Being careless, we supposed that should anything bad occur in this second thread (timeouts, invalid login/password, etc.), the system will simply not be able to post, which was not a problem for us. We were wrong, and the whole web application restarted because of this. (This was not the case in ASP.NET 1.x and was previously discussed by others).

In any case, here's some sample code to run the Twitter library asynchronously, including a try/catch.

using System;
using System.Collections.Generic;
using System.Text;
 
namespace LavaBlast.Util.Twitter
{
    public class AsyncTwitter
    {
        public void Update(string userName, string password, string status)
        {
            TwitterDelegate caller = new TwitterDelegate(UpdateTwitter);
            caller.BeginInvoke(userName, password, status, new AsyncCallback(CallbackMethod), caller);
        }
 
        protected delegate void TwitterDelegate(string userName, string password, string status);
        protected static void CallbackMethod(IAsyncResult ar)
        {
            TwitterDelegate caller = (TwitterDelegate)ar.AsyncState;
            caller.EndInvoke(ar);
        }
        protected static void UpdateTwitter(string userName, string password, string status)
        {
            try
            {
                Twitter t = new Twitter();
                t.Update(userName, password, status, Twitter.OutputFormatType.XML);
            }
            catch (Exception ex)
            {
                LavaBlast.ElectronicJournal.Error("Unable to post to twitter.", ex);
                // ignore. 
            }
        }
    }
}

The lesson learned is unhandled exceptions in other threads can wreak havoc on your ASP.NET application. To help debug these kinds of errors when they occur, I do suggest you setup the HttpModule developed by Peter A. Bromberg that adds the actual exception in your Event Log. Peter describes the problem in more detail than I do, and is worth a read.

Have a Happy Halloween! (Halloween will be weird for us in 2008 because we were hit by the year's first snowstorm on Tuesday.)

halloween

kick it on DotNetKicks.com