h1

AppDomain Events and HttpModules

November 9, 2007

In a previous post I discussed the cause of an error: A process serving application pool terminated unexpectedly.
I realised that I had a need to catch unhandled 2.0 exceptions and started looking at the AppDomain class.

An Application Domain serves as a boundary so that the runtime can isolate applications from one another and using AppDomain.CurrentDomain, you can retrieve the AppDomain instance that a thread is running under.

One of the events of the AppDomain class is the UnhandledException event and it is this that I could utilise to catch any unhandled exception no matter what thread it runs under.

Therefore if I create a new HttpModule I can provide an event handler for this event and can record these exceptions when that is called.

Pooled HttpApplications

One mistake I didn’t want to make though was one that others had made – simply hooking up an event handler in the Init() method of the HttpModule as usual without taking into account multiple application instances…

The ASP.NET pipeline keeps a pool of HttpApplication objects ready to serve requests and each one of these objects has a collection of HttpModules (and thus each HttpModule provides event handlers for its own HttpApplication).

Therefore because for any one AppDomain you have a number of HttpApplication/HttpModule instances I need to ensure that I only hook up to AppDomain events once.

I can achieve this by making the HttpModule thread/multiple instance aware using static members:

public class UnhandledModule : IHttpModule
{
#region static members – note, must be thread safe

static int unhandledExceptionCount = 0;
static object lockObject = new object();
static bool initialized = false;

#endregion

public void Init(HttpApplication context)
{
// We only want one instance of a HttpModule to handle event.
if
( !initialized)
{
// create a lock so no other instance can affect the static variable
lock (lockObject)
{
if( !initialized)
{

AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

initialized = true;
}
} // now lock is released and the static variable is true..
}}}

So with the above code I have ensured that only one HttpModule instance will provide an event handler for the unhandled exception event.
I can be confident that this will not happen multiple times and bloat the memory of the application.

However I have concerns…

The idea for this was obtained from an MSDN article describing the 2.0 unhandled exceptions behaviour change.

What I am concerned about is that because multiple HttpApplication instances are kept in a pool and managed – if any are killed off by the runtime because they are deemed unnecessary (the requests are less frequent for instance), how do I know that the single instance that provided event handler is still alive?

We’ve tested and installed the “UnhandledModule” as described above, yet our application still errors without catching the exception. My current guess is that it is caused by no event handler existing anymore.

I’ve posed this question on the ASP.NET forums and am still figuring out an answer – do the HttpApplication instance all stay alive?
And if not, should I have code in the Dispose() method of the one instance that has the event handler, so it can release the static initialized variable?
Hopefully if I can’t find it, someone out there knows the answer.

Advertisements

One comment

  1. I stumbled upon your post today, and thought I’d add some words of wisdom. While HttpApplications are pooled there is an alternative to resolve your need. This is what I do inside my applications to secure objects from deconstructing, and sharing across multiple HttpApplication’s

    public class MyCustomAppInstance : HttpApplication
    {
    public MyCustomAppInstance()
    {
    InitializeEngine();
    }
    private void InitializeEngine()
    {
    // HttpApplication are pooled by ASP.NET, the engine is to
    // serve as a singleton to all requests. Put the engine in the cache.

    Cache runtimeCache = System.Web.HttpRuntime.Cache;
    MyCustomEngine engine = runtimeCache.Get(“MyCustomEngine”) as MyCustomEngine;
    if (engine == null)
    runtimeCache.Add(“MyCustomEngine”, new MyCustomEngine(), null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration,
    CacheItemPriority.NotRemovable, null);
    }
    public MyCustomEngine Engine
    {
    get
    {
    return contextCache.Get(“MyCustomEngine”) as MyCustomEngine;
    }
    }
    }

    To explain why this works, the cache is maintained as a whole for the AppDomain not the HttpApplication; you could do the same logic within the HttpModule v.s. creating a derived HttpApplication class.



Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: