我通过该ApplicationHost.CreateApplicationHost
方法托管 ASP.NET 运行时。当我web.config
在应用程序运行时修改时,我看到很多第一次机会ThreadAbortException
被抛出。这是在我的应用程序崩溃之前。我假设这是因为运行时检测到配置更改并想要重新启动。
这对我们来说并不是一个真正受支持的场景,所以如果我可以关闭自动重新加载,我会更喜欢。
有谁知道如何做到这一点?
我通过该ApplicationHost.CreateApplicationHost
方法托管 ASP.NET 运行时。当我web.config
在应用程序运行时修改时,我看到很多第一次机会ThreadAbortException
被抛出。这是在我的应用程序崩溃之前。我假设这是因为运行时检测到配置更改并想要重新启动。
这对我们来说并不是一个真正受支持的场景,所以如果我可以关闭自动重新加载,我会更喜欢。
有谁知道如何做到这一点?
实际上,前两个答案是不正确的。防止这种回收发生是可能的,而且非常容易,并且至少从 IIS6 开始就可以使用此功能。
DWORD
将注册表设置更改为HKLM\SOFTWARE\Wow6432Node\Microsoft\ASP.NET\FCNMode
值1
,这将禁用所有文件更改通知。
不要被位置所迷惑:Wow6432Node
在这种情况下,它不会影响您的 Web 应用程序的位数。
如果您使用的是 .NET 4.5,那么现在可以在每个站点级别禁用此功能,只需在您的web.config
:
<httpRuntime fcnMode="Disabled"/>
最后,并且(至少)从 IIS6 开始,有一个设置被称为DisallowRotationOnConfigChange
仅适用于应用程序池的设置(至少我认为 MSDN 上的文本试图这么说,但我还没有测试过)。将其设置为true
并且更改应用程序池的配置不会导致立即回收。
最后一个设置也可以从应用程序池的高级设置中设置:
对于使用 ASP.NET 1.0 或 1.1 的(旧)网站,存在一个已确认的错误,该错误可能导致文件更改的快速和重复回收。当时的解决方法类似于MartinHN在主要问题下建议的方法,即在您的 中类似于以下内容web.config
:
<compilation
debug="false"
defaultLanguage="vb"
numRecompilesBeforeAppRestart="5000">
这不会禁用回收,但仅在进行5000 次重新编译后才会禁用。这个数字是否有用取决于您的应用程序的大小。微软并没有明确说明重新编译到底是什么。但是,默认值为15。
顺便说一句:无论 .NET 或 Windows 的版本如何,我们发现当应用程序从共享运行并在负载平衡的环境中使用时,站点会不断循环使用。解决它的唯一方法是将该FNCMode
设置添加到注册表中(但现在有更多细粒度的选项)。
据我所知,无法禁用此行为,更改 webconfig 会强制重新启动应用程序。
更新:实际上是可能的,有很多方法,有据可查,如本答案所述*
原答案:
这里有一个类似的问题,仅供参考。我发现了可能有帮助的其他信息。
配置更改导致应用
程序域重新启动 Web.config 文件中配置设置的更改间接导致应用程序域重新启动。此行为是设计使然。您可以选择使用 configSource 属性来引用在进行更改时不会导致重新启动的外部配置文件。有关详细信息,请参阅节元素继承的常规属性中的configSource 。
*免责声明:我写了另一个答案,通常不会进行自我参考,但发现它足够相关,因为在这篇文章发布 8 年后它可以链接到这里,它真的很不一样:通过点击 IIS 前面的解决方案很容易-end,并且从 ASP.NET 1.0 开始存在变通方法。
我遇到了一个更大的问题——对 AppDomain 基本目录中的任何文件或子文件夹的更改都会导致托管环境关闭。这对我们的应用程序来说是一个相当大的问题,因为我们在同一个 AppDomain 中运行 WPF UI,我们无法在不干扰用户的情况下重新启动它。
我真的很想避免为应用程序的基于 Web 的部分运行单独的 AppDomain,所以我使用 Reflector 进行了一些挖掘。我发现罪魁祸首是内部类FileChangesMonitor
。
所以我写了一个可怕的反射黑客来解决这个问题。我想我会把它贴在这里作为其他有同样问题的人的潜在解决方案。您只需要调用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);
}
}
一个解决方案是将以下元素添加到 web.config 部分:
<httpRuntime
waitChangeNotification="315360000"
maxWaitChangeNotification="315360000"
/>
正如 jfburdet 所提到的,解决方案是使用 waitChangeNotification 和 maxWaitChangeNotification。
话虽如此,如果 ASP.NET 在混合模式下运行,您应该知道它们不适用于 IIS 7:http ://forums.iis.net/t/1149344.aspx