I got an email with some questions around application domains, application pools and unhandled exceptions from a developer that was frequently seeing his website crash, and also had some related issues with session loss in his application.
From what I read, my understanding is that a website has an app pool associated with it. This app pool leads to the creation of a w3wp.exe process. Inside this app pool/w3wp.exe process, an application domain is created.
Me: This is correct. In IIS you can create different application pools that have different health monitoring settings, run under different user contexts etc. and when you create a web site you choose which application pool it will run under. Each application pool will then spawn it’s own w3wp.exe process (or multiple if you have web gardening turned on) when the first request comes in.
The process (w3wp.exe) contains multiple application domains, typically a shared domain, a default domain, a system domain and one application domain per web application (virtual directory marked as application).
An application domain recycling is different than an application pool/process (w3wp.exe) recycling, right?
Me: Yes. An app domain can recycle without recycling the process. Simplified an app domain is a process within the process with it’s own statics (cache/session etc.), but all app domains in the process share the same GC, threadpool, finalizer thread etc.
An app domain recycle is triggered by a few things like web.config changes, directory name changes etc. You can find most of the app domain recycle reasons in this post. When an app domain recycles the process stays up, however when the process goes down the app domains in the process will of course also go down.
Can unhandled exceptions cause the application domain to recycle?
Me: It depends on what you mean by unhandled exceptions. In ASP.NET there is the concept of unhandled exceptions that are caught by the global error handler or page error handler. i.e. the ones that give you the yellow exception output when you view a page. They will be listing as unhandled exceptions in event viewer, but in reality they are handled by the page error handler, and they will neither crash the app domain or the application/w3wp.exe process.
If on the other hand you have an exception that occurs on a non-request thread, such as a timer thread or the finalizer thread and you don’t have a try/catch block around it, it is really an unhandled exception, and such unhandled exceptions will cause the process to go down and take all the app domains with it.
What exactly happens inside the application domain when an unhandled exception occurs ?
Me: The process shuts down, and the app domains are unloaded so anything inside it is gone including session vars etc.
Is there a setting in any of the config files that will prevent the application domain from recycling?
Me: There is a legacyUnhandledExceptionPolicy see this post for more info, that will cause a 2.0 process to behave as 1.1, i.e. not shut down the process and instead just quit processing the current thread of execution. I would seriously advice against using it though other than as a temporary measure while you troubleshoot the unhandled exception as it may cause your process to behave erratically, since you don’t really know what has processed and what hasn’t. For example if an exception occurs during finalization you will not know if you have released all the native handles you were supposed to or not.