views:

1892

answers:

4

I'm hosting the ASP.NET runtime via the ApplicationHost.CreateApplicationHost method. When I modify the web.config while the application is running, i see lots of first chance ThreadAbortExceptions thrown. This is right before my application comes crashing down. I'm assuming this is because the runtime has detected changes to the configuration and wants to restart.

This isn't really a supported scenario for us, so i'd prefer if I could just switch off the automatic reloading.

Does anyone know how to do this?

+11  A: 

As far as I am aware there is no way to disable this behavior, changes to the webconfig force the application to be restarted.

There is a similar question here just for other reference.

Edit: Found additional info that may be helpful.

Configuration Changes Cause a Restart of the Application Domain
Changes to configuration settings in Web.config files indirectly cause the application domain to restart. This behavior occurs by design. You can optionally use the configSource attribute to reference external configuration files that do not cause a restart when a change is made. For more information, see configSource in General Attributes Inherited by Section Elements.

From This MSDN Article

Quintin Robinson
Correct me if I'm wrong, but I believe that external configuration files will also restart the application?
SkippyFire
OK I guess that MSDN article says that the don't cause application restarts, but does that mean that the config settings don't get loaded right away?
SkippyFire
OK I just did some investigation, and on my ASP.NET 3.5 site, the App Pool did **NOT** restart, and the updated Setting Value **WAS** reflected in the web page.However, I still feel like I have seen a web app that WOULD reset when external configuration files were changed. Maybe there was something special about that app, or maybe it was an older version of ASP.NET.
SkippyFire
+5  A: 

I ran in to an even bigger problem along the same lines - changes to any file or sub-folder in the AppDomain base directory cause the hosting environment to shutdown. This is a pretty big issue for our application as we're running a WPF UI in the same AppDomain and we can't restart it without being distruptive to the user.

I really wanted to avoid having to run a separate AppDomain for the web based part of the application so I did some digging with Reflector. I found that the culprit was the internal class FileChangesMonitor.

So I wrote a horrible horrible reflection hack to solve the problem. I thought I'd post it here as a potential solution for anyone else having the same problem. You just need to call HttpInternals.StopFileMonitoring() to disable shutdown on file/folder changes.

internal static class HttpInternals
{
    private static readonly FieldInfo s_TheRuntime = typeof(HttpRuntime).GetField("_theRuntime", BindingFlags.NonPublic | BindingFlags.Static);

    private static readonly FieldInfo s_FileChangesMonitor = typeof(HttpRuntime).GetField("_fcm", BindingFlags.NonPublic | BindingFlags.Instance);
    private static readonly MethodInfo s_FileChangesMonitorStop = s_FileChangesMonitor.FieldType.GetMethod("Stop", BindingFlags.NonPublic | BindingFlags.Instance);

    private static object HttpRuntime
    {
        get
        {
            return s_TheRuntime.GetValue(null);
        }
    }

    private static object FileChangesMonitor
    {
        get
        {
            return s_FileChangesMonitor.GetValue(HttpRuntime);
        }
    }

    public static void StopFileMonitoring()
    {
        s_FileChangesMonitorStop.Invoke(FileChangesMonitor, null);
    }
}
Jacob Stanley
But appDomains are intended to reflect the, y'know, application domain - something that is clearly different between WPF and web. You're using the object in a way not it was not intended to be used.
annakata
That's true, and I have indeed considered the pros and cons of using multiple AppDomains.I ended up coming to the conclusion that running multiple AppDomains would add more complexity to the application than this approach does.I'd love to hear any more opinions on the issue.
Jacob Stanley
@Jacob Stanley: First of all thanks for this solution. I have only one question, how can I restore file monitoring? For example after updating some dll files manually I want to restore normal website behaviour.
AareP
That's probably a lot more complicated :)If you're comfortable with Reflector, you can see what System.Web.FileChangesMonitor.Stop() does, and perhaps try to reverse it. It looks like ASP.NET usually only uses the Stop() method when it's shutting down.FileChangesMonitor has some methods on it called StartListeningToLocalResourceDirectory and some other Start* methods which look promising. If you could figure out what the HttpRuntime class does to initialize the FileChangesMonitor, you'd be on the right track.Sounds even dodgier than what I was originally doing though! :)
Jacob Stanley
@Jacob Stanley: Yes, it's pretty dodgy, I'm trying to update a single function of a running precompiled website. Using Reflector and Reflexil to accomplish that :)
AareP
Although it seems that updating method in runtime is not yet possible. There's a method PrepareMethod() for compiling IL-code, but not for re-compiling. So, once the method is called replacing it's IL-code will do nothing.
AareP
+2  A: 

A solution would be adding following element to web.config section :

<httpRuntime
    waitChangeNotification="315360000"
    maxWaitChangeNotification="315360000"
/>
jfburdet
A: 

As mentioned by jfburdet the solution is to use waitChangeNotification and maxWaitChangeNotification.

That being said, you should know they don't work on IIS 7 if ASP.NET is run in mixed mode: http://forums.iis.net/t/1149344.aspx

Hanan Schwartzberg