如何防止 ASP.NET 应用程序在 web.config 修改后重新启动?

发布于 2024-07-14 17:41:15 字数 285 浏览 6 评论 0原文

我通过 ApplicationHost.CreateApplicationHost 方法托管 ASP.NET 运行时。 当我在应用程序运行时修改 web.config 时,我看到很多第一次抛出 ThreadAbortException 的机会。 这是在我的应用程序崩溃之前。 我假设这是因为运行时已检测到配置更改并想要重新启动。

这对我们来说并不是真正受支持的场景,所以我希望我可以关闭自动重新加载。

有谁知道如何做到这一点?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

何时共饮酒 2024-07-21 17:41:16

事实上,前两个答案都是错误的。 防止这种回收发生是可能的,而且非常容易,并且该功能至少从 IIS6 开始就可用。

方法 1(系统范围)

HKLM\SOFTWARE\Wow6432Node\Microsoft\ASP.NET\FCNModeDWORD 注册表设置更改为值 1 ,这将禁用所有文件更改通知。

不要对位置感到困惑:在这种情况下,Wow6432Node 对 Web 应用程序的位数没有影响。

方法 2 (.NET 4.5+)

如果您使用 .NET 4.5,则现在可以要在每个站点级别禁用此功能,只需在 web.config 中使用以下内容:

<httpRuntime fcnMode="Disabled"/> 

方法 3 (IIS6+)

最后,并且(至少)自 IIS6 以来,有一个名为 DisallowRotationOnConfigChange< /a> 仅作为应用程序池的设置(至少我认为 MSDN 上的文本是这么说的,但我还没有测试过)。 将其设置为true,对应用程序池配置的更改不会导致立即回收。

最后一个设置也可以从应用程序池的高级设置中进行设置:

Disable Recycling for Configuration Change

方法 4 (ASP.NET 1.0 和 1.1)

对于使用 ASP.NET 1.0 或 1.1 的(旧)网站,有一个已确认的bug 可能会导致文件更改快速重复回收。 当时的解决方法类似于 MartinHN 在主要问题下建议的内容,即,类似于以下内容的 web.config

<compilation 
   debug="false"
   defaultLanguage="vb"
   numRecompilesBeforeAppRestart="5000">

这不会禁用回收,但仅在发生 5000 次重新编译后才会禁用。 该数字是否有用取决于您的应用程序的大小。 微软没有明确说明重新编译到底是什么。 但默认值为 15

顺便说一句:无论 .NET 或 Windows 的版本如何,我们发现当应用程序从共享运行并在负载平衡环境中使用时,站点会不断回收。 解决这个问题的唯一方法是将 FNCMode 设置添加到注册表(但现在有更细粒度的选项)。

Actually, the first two answers are incorrect. It is possible, and quite easy, to prevent this recycling from happening, and this feature has been available since at least IIS6.

Method 1 (system wide)

Change the DWORD registry setting for HKLM\SOFTWARE\Wow6432Node\Microsoft\ASP.NET\FCNMode to the value 1, which will disable all file change notifications.

Don't be confused by the location: Wow6432Node has, in this case, no influence on the bitness of your web application.

Method 2 (.NET 4.5+)

If you are using .NET 4.5, then it is now possible to disable this on a per-site level, simply use the following in your web.config:

<httpRuntime fcnMode="Disabled"/> 

Method 3 (IIS6+)

Finally, and also (at least) around since IIS6, there's a setting called DisallowRotationOnConfigChange as a setting for only the application pool (at least that is what I think the text on MSDN tries to say, but I haven't tested it). Set it to true and changes to the configuration of the application pool will not result in an immediate recycle.

This last setting can also be set from Advanced Settings of the application pool:

Disable Recycling for Configuration Change

Method 4 (ASP.NET 1.0 and 1.1)

For (old) websites using ASP.NET 1.0 or 1.1, there is a confirmed bug that can cause rapid and repeated recycles on file changes. The workaround at the time was similar to what MartinHN suggested under the main question, namely, something like the following in your web.config:

<compilation 
   debug="false"
   defaultLanguage="vb"
   numRecompilesBeforeAppRestart="5000">

This does not disable recycling, but it does so only after 5000 recompilations have taken place. Whether this number is useful depends on the size of your application. Microsoft does not clearly say what a recompilation really is. The default, however, is 15.

As an aside: regardless of the version of .NET or Windows, we find that when the application is run from a share and used in a load-balanced environment, that the site recycles continuously. The only way to solve it was by adding that FNCMode setting to the registry (but now there are more fine-grained options).

花想c 2024-07-21 17:41:16

据我所知,没有办法禁用此行为,更改 webconfig 会强制重新启动应用程序。

更新:实际上是可能的,有很多方法,有详细记录,正如此答案中的解释*

原始答案:

有一个类似的问题此处仅供其他参考。 我找到了可能有帮助的其他信息。

配置更改导致重新启动
应用程序域的

更改为
Web.config 中的配置设置
文件间接导致应用程序
域以重新启动。 这种行为
是有意而为之的。 您可以选择
使用 configSource 属性
引用外部配置文件
不会导致重新启动时
改变发生了。 了解更多信息,
请参阅 常规属性中的 configSource
由部分元素继承。

来自这篇 MSDN 文章

* 免责声明:我写了另一个答案,通常不会进行自我引用,但发现它足够相关,可以链接到这里,因为在这篇文章发布 8 年后,它确实非常不同:通过单击解决方案非常简单IIS 前端,自 ASP.NET 1.0 起就存在解决方法。

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

Update: it is actually possible, there are a number of methods, well documented, as explained in this answer*

Original answer:

There is a similar question here just for other reference. I 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

* Disclaimer: I wrote the other answer and normally wouldn't make a self-reference, but find it relevant enough to link here since 8 years after this post it is really quite different: a solution is very easy by clicking through the IIS front-end, and workarounds exist since ASP.NET 1.0.

稀香 2024-07-21 17:41:16

我遇到了同样的更大问题 - 对 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);
    }
}

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);
    }
}
找个人就嫁了吧 2024-07-21 17:41:16

解决方案是将以下元素添加到 web.config 部分:

<httpRuntime
    waitChangeNotification="315360000"
    maxWaitChangeNotification="315360000"
/>

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

<httpRuntime
    waitChangeNotification="315360000"
    maxWaitChangeNotification="315360000"
/>
戒ㄋ 2024-07-21 17:41:16

正如 jfburdet 所提到的,解决方案是使用 waitChangeNotification 和 maxWaitChangeNotification。

话虽如此,您应该知道,如果 ASP.NET 在混合模式下运行,它们在 IIS 7 上不起作用: http://forums.iis.net/t/1149344.aspx

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文