37

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

这对我们来说并不是一个真正受支持的场景,所以如果我可以关闭自动重新加载,我会更喜欢。

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

4

5 回答 5

33

实际上,前两个答案是不正确的。防止这种回收发生是可能的,而且非常容易,并且至少从 IIS6 开始就可以使用此功能。

方法 1(系统范围)

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

不要被位置所迷惑:Wow6432Node在这种情况下,它不会影响您的 Web 应用程序的位数。

方法 2 (.NET 4.5+)

如果您使用的是 .NET 4.5,那么现在可以在每个站点级别禁用此功能,只需在您的web.config

<httpRuntime fcnMode="Disabled"/> 

方法 3 (IIS6+)

最后,并且(至少)从 IIS6 开始,有一个设置被称为DisallowRotationOnConfigChange仅适用于应用程序池的设置(至少我认为 MSDN 上的文本试图这么说,但我还没有测试过)。将其设置为true并且更改应用程序池的配置不会导致立即回收。

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

为配置更改禁用回收

方法 4(ASP.NET 1.0 和 1.1)

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

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

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

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

于 2015-07-17T07:04:45.487 回答
28

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

更新:实际上是可能的,有很多方法,有据可查,如本答案所述*

原答案:

这里有一个类似的问题,仅供参考。我发现了可能有帮助的其他信息。

配置更改导致应用
程序域重新启动 Web.config 文件中配置设置的更改间接导致应用程序域重新启动。此行为是设计使然。您可以选择使用 configSource 属性来引用在进行更改时不会导致重新启动的外部配置文件。有关详细信息,请参阅节元素继承的常规属性中的configSource 。

来自这篇 MSDN 文章

*免责声明:我写了另一个答案,通常不会进行自我参考,但发现它足够相关,因为在这篇文章发布 8 年后它可以链接到这里,它真的很不一样:通过点击 IIS 前面的解决方案很容易-end,并且从 ASP.NET 1.0 开始存在变通方法。

于 2009-03-05T07:04:30.973 回答
20

我遇到了一个更大的问题——对 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);
    }
}
于 2009-03-10T12:16:28.123 回答
10

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

<httpRuntime
    waitChangeNotification="315360000"
    maxWaitChangeNotification="315360000"
/>
于 2009-08-24T09:54:04.983 回答
0

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

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

于 2009-12-10T09:20:25.557 回答