Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delay AppDomain recycle on folder change

Tags:

asp.net

iis

iis-7

I am developing a ASP.NET 4 app and use full IIS also during development (for several reasons; one that I use multiple domains pointing to the app).

When I build the project in Visual Studio IIS does recycle the AppDomain and loads the newly built one, but now I have the problem, that it does this "to fast".
I have some scripts on my page which trigger an App-Startup as soon as it is recycled (like constantly open SignalR channels) and so a new AppDomain is already created when only half of my project is built and so it recycles a second time which then actually crashes, because I have a PreApplicationStartMethod copying some Plugin-DLL's to a Shadow-Copy directory, but the "old DLL's" are still locked by the first AppDomain.
If I then wait ~10s everything is fine and my "new AppDomain" starts up.
I though of solving this problem by simply telling IIS to wait with the rececly for a few seconds so the build can complete after it detects the changes in the bin folder.

So to my main question:
Is it possible to delay an AppDomain recycle under IIS?

like image 523
Christoph Fink Avatar asked Aug 05 '13 17:08

Christoph Fink


2 Answers

If you can't delay the AppDomain recycle, you may want to disable it.

There is a File Change Notification (FCN) behavior which can be disabled.

Registry

Originally, it is a DWORD registry entry at HKLM\Software\Microsoft\ASP.NET\FCNMode, setting the value to 1 should disable it.

Code (hack) up to .NET Framework 4.0

This hack might work with 2.0-3.5 and 4.0 frameworks.

//Disable AppDomain restart on file change

System.Reflection.PropertyInfo p = 
    typeof(System.Web.HttpRuntime).GetProperty("FileChangesMonitor", 
        System.Reflection.BindingFlags.NonPublic 
        | System.Reflection.BindingFlags.Public 
        | System.Reflection.BindingFlags.Static);

object fcm = p.GetValue(null, null);

System.Reflection.MethodInfo m = fcm.GetType().GetMethod("Stop",
    System.Reflection.BindingFlags.Instance 
    | System.Reflection.BindingFlags.NonPublic); 
m.Invoke(fcm, new object[] { }); 

Drop it in your Global.asax Application_Start. See here.

If you want to disable the monitoring for specific paths or files you can use StopMonitoringFile or StopMonitoringPath methods from FileChangesMonitor. However, Bin directory is a special dir and may be immune to these two methods.

At least, you can play with the _dirMonSpecialDirs field and call StopMonitoring() on your Bin directory.

.NET Framework 4.5

In .NET Framework 4.5, a HttpRuntimeSection.FcnMode property exists. There is not so much documentation about it but you can use <httpRuntime fcnMode="Disabled"/>.

like image 182
JoeBilly Avatar answered Oct 27 '22 08:10

JoeBilly


Found an article explaining this: http://www.ipreferjim.com/2012/04/asp-net-appdomains-and-shadow-copying/

The settings I searched for are waitChangeNotification and maxWaitChangeNotification as attributes to httpRuntime.

Sadly it seems to not have solved my problem - need to investigate more...

like image 23
Christoph Fink Avatar answered Oct 27 '22 08:10

Christoph Fink