我正在使用ApplicationHost.CreateApplicationHost
方法托管ASP.NET运行时。当应用程序在运行时修改web.config
文件时,会看到大量的ThreadAbortException
异常被抛出。这是在我的应用程序崩溃之前发生的。我假设这是因为运行时检测到配置更改并想要重新启动。
这对我们来说不是一个真正支持的场景,因此我希望我可以关闭自动重新加载。
有人知道如何做吗?
我正在使用ApplicationHost.CreateApplicationHost
方法托管ASP.NET运行时。当应用程序在运行时修改web.config
文件时,会看到大量的ThreadAbortException
异常被抛出。这是在我的应用程序崩溃之前发生的。我假设这是因为运行时检测到配置更改并想要重新启动。
这对我们来说不是一个真正支持的场景,因此我希望我可以关闭自动重新加载。
有人知道如何做吗?
实际上,前两个答案是不正确的。防止这种回收发生是可能的,而且非常容易,自至少IIS6以来就有了这个功能。
更改HKLM\SOFTWARE\Wow6432Node\Microsoft\ASP.NET\FCNMode
的DWORD
注册表设置为值1
,这将禁用所有文件更改通知。
不要被位置所迷惑:Wow6432Node
在这种情况下对您的Web应用程序的位数没有影响。
如果您使用的是.NET 4.5,则现在可以在每个站点上禁用此功能,只需在您的web.config
中使用以下内容:
<httpRuntime fcnMode="Disabled"/>
最后,也是自IIS6起存在的设置,名为DisallowRotationOnConfigChange
的设置仅适用于应用程序池(至少我认为MSDN上的文本是这样说的,但我还没有测试过)。将其设置为true
,并且对应用程序池的配置更改将不会立即导致重新启动。
此设置也可以从应用程序池的高级设置中设置:
对于使用ASP.NET 1.0或1.1的(旧)网站,存在一个已确认的错误(bug),可能会导致文件更改时的快速和重复的重新加载。当时的解决方法类似于主问题下MartinHN建议的方式,即在您的web.config
中添加以下内容:
<compilation
debug="false"
defaultLanguage="vb"
numRecompilesBeforeAppRestart="5000">
FNCMode
设置添加到注册表中(但现在有更精细的选项可供选择)。web.config
进行设置并且是否可以防止所有文件更改时重新加载。请注意,此应用程序不是通过 IIS 运行的,而是由 WPF 应用程序托管的 ASP.NET AppDomain。方法1并不是一个真正的选择,因为它会影响其他应用程序。 - Jacob Stanleyweb.config
中的fcnMode
(方法2)还是在AppPool设置中设置它(方法3),都不太重要。同一站点的web.config
可以被多个AppPools使用,尽管通常情况下同一AppPool用于多个站点,在这种情况下,最好使用具有fcnMode
的方法2(更好的每个站点粒度)。请注意,您甚至可以通过在其中添加web.config
来为一个站点中的单独目录设置fcnMode
。 - AbelDisallowRotationOnConfigChange
设置仅适用于应用程序池的设置更改,而不适用于web.config中的更改。有关更多信息,请参见此线程。 - Azimuth我在同一问题上遇到了更大的问题 - 在AppDomain基目录中更改任何文件或子文件夹都会导致托管环境关闭。对于我们的应用程序来说,这是一个相当大的问题,因为我们在同一AppDomain中运行一个WPF UI,而且我们不能在不干扰用户的情况下重新启动它。
我真的想避免必须为基于Web的应用程序运行单独的AppDomain,所以我使用Reflector进行了一些挖掘。 我发现罪魁祸首是内部类FileChangesMonitor
。
因此,我写了一个非常可怕的反射hack来解决这个问题。 我认为我应该将其发布在这里,作为可能的解决方案供其他遇到同样问题的人参考。 您只需要调用HttpInternals.StopFileMonitoring()
来禁用文件/文件夹更改时的关闭。
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);
}
}
<httpRuntime
waitChangeNotification="315360000"
maxWaitChangeNotification="315360000"
/>
正如jfburdet所提到的,解决方案是使用waitChangeNotification和maxWaitChangeNotification。
话虽如此,您应该知道,如果在混合模式下运行ASP.NET,则它们不适用于IIS 7:http://forums.iis.net/t/1149344.aspx