我通过该ApplicationHost.CreateApplicationHost
方法托管ASP.NET运行时.当我修改web.config
应用程序运行时,我看到很多第一次机会ThreadAbortException
抛出.这是在我的应用程序崩溃之前.我假设这是因为运行时已检测到配置更改并想要重新启动.
这对我们来说并不是真正受支持的场景,所以我更愿意,如果我可以关闭自动重新加载.
有谁知道如何做到这一点?
据我所知,没有办法禁用此行为,对webconfig的更改会强制重新启动应用程序.
更新:它实际上是可能的,有很多方法,有详细记录,如本答案所述*
原始答案:
还有一个类似的问题在这里只是为其他参考.我发现了可能有用的其他信息.
配置更改导致重新启动应用程序域
对Web.config文件中的配置设置的更改会间接导致应用程序域重新启动.此行为是通过设计发生的.您可以选择使用configSource属性来引用在进行更改时不会导致重新启动的外部配置文件.有关更多信息,请参阅由Section Elements继承的General Attributes中的 configSource .
来自此MSDN文章
*免责声明:我写了另一个答案,通常不会自我引用,但发现它足够相关链接在这里,因为这篇文章发布后8年真的很不一样:通过点击IIS前端,解决方案非常简单-end,自ASP.NET 1.0以来就存在变通方法.
实际上,前两个答案是不正确的.这是可能的,而且很容易,以防止这种循环的发生,并且至少自IIS6这个功能已经可用.
将DWORD
注册表设置更改为该HKLM\SOFTWARE\Wow6432Node\Microsoft\ASP.NET\FCNMode
值1
,这将禁用所有文件更改通知.
不要被位置混淆:Wow6432Node
在这种情况下,不会影响Web应用程序的位数.
如果您使用的是.NET 4.5,那么现在可以在每个站点级别禁用此功能,只需在以下位置使用以下内容web.config
:
最后,并且(至少)自IIS6以来,有一个设置被DisallowRotationOnConfigChange
称为仅应用程序池的设置(至少这是我认为MSDN上的文本试图说,但我还没有测试过它).将其设置为true
并更改应用程序池的配置不会导致立即回收.
也可以从应用程序池的"高级设置"设置最后一个设置:
对于使用ASP.NET 1.0或1.1的(旧)网站,有一个确认的错误可能导致文件更改的快速和重复循环.当时的解决方法类似于MartinHN在主要问题下提出的建议,即类似以下内容web.config
:
这不会禁用回收,但只有在进行了5000次重新编译后才会这样做.此数字是否有用取决于您的应用程序的大小.微软没有明确说明重新编译是什么.但是,默认值为15.
顺便说一下:无论.NET或Windows版本如何,我们都会发现,当应用程序从共享运行并在负载均衡的环境中使用时,该站点将不断循环使用.解决问题的唯一方法是将该FNCMode
设置添加到注册表中(但现在有更多细粒度的选项).
我在同一行中遇到了更大的问题 - 对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部分: