应用池回收后,自定义配置部分为 null

本文关键字:配置部 null 自定义 应用 | 更新日期: 2023-09-27 17:56:16

最近我们在读取配置文件时在生产中遇到了以下问题。

对象引用未设置为对象的实例。 (C:''applications''SampleWebsite''web.config line 105) at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] 键, 部分输入输入, 布尔值受信任, 工厂记录 工厂记录, 节记录部分记录, 对象父结果) at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord 工厂记录, 节记录节记录, 对象父结果, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject) at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) at System.Configuration.BaseConfigurationRecord.GetSection(String 配置键)在 System.Configuration.ConfigurationManager.GetSection(String 部分名称)在 SampleWebsite.Configuration.CustomConfigurationSection.get_Current() 在 c:''Builds''1''SampleWebsite''Sources''Source''SampleWebsite''Configuration''CustomConfigurationSection.cs:line 69 在 SampleWebsite.Security.AuthorizationManager.CheckAccess(AuthorizationContext 上下文)在 c:''Builds''1''SampleWebsite''Sources''Source''SampleWebsite''Security''AuthorizationManager.cs:line 161 在 System.IdentityModel.Services.ClaimsPrincipalPermission.Demand() at System.Security.PermissionSet.DemandNonCAS() at SampleWebsite.CustomController.Test() in c:''Builds''1''SampleWebsite''Sources''Source''SampleWebsite''Controllers''CustomController.cs:line 125 在 lambda_method(闭包、对象、对象[] ) 在 System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c_DisplayClass13.b_c(Object instance, Object[] methodParameters) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object 实例, 对象[] 参数) 在 System.Threading.Tasks.TaskHelpers.RunSyncly[TResult](Func'1 func, 取消令牌取消令牌)

我们在Windows Server 2012上的IIS 8上使用.NET 4.5。此问题有时(并非总是如此!)在回收应用程序池后发生。如果出现问题,我们必须停止应用程序池并启动应用程序池。回收应用程序池无济于事,重新启动网站也无济于事。

配置文件中未发生任何更改。我们注意到的唯一真正的区别是对网站本身提出了更多请求。

由于我们最初认为这可能是争用条件,因此我们已将应用程序池安排在确定没有请求发送到网站的特定时间回收。

在关闭向

此站点发送请求的应用程序时和再次启动之前,已选择回收时间。

应用程序池设置了以下配置选项:

  • 自动启动:真
  • 启动模式:始终运行
  • 立即启动应用程序池:true

该网站设置了以下选项:

  • 启用预加载:真
  • 自动启动:真

以前有人遇到过这个问题吗?

任何帮助将不胜感激!

编辑:

这基本上是自定义配置部分代码中的内容:

public sealed class CustomConfigurationSection : ConfigurationSection
{
    private static CustomConfigurationSection _current;
    public static CustomConfigurationSection Current
    {
        get
        {
            return _current
                ?? (_current = ConfigurationManager.GetSection(CustomSectionName) as CustomConfigurationSection);
        }
    }
}

在回收应用程序池并且_current字段(静态)为空并且需要从配置文件中再次读取后,nullref 出现在 ConfigurationManager.GetSection() 中。

应用池回收后,自定义配置部分为 null

您使用的空合并运算符不是线程安全的。向 getter 添加一个锁定变量:

private static CustomConfigurationSection _current;
private static readonly object _lock = new object();
public static CustomConfigurationSection Current
{
    get
    {
        lock(_lock) {
            return _current
                ?? (_current = ConfigurationManager.GetSection(CustomSectionName) as CustomConfigurationSection);
        }
    }
}

也有可能ConfigurationManager在回收应用程序池后不久没有返回预期值(我看不到在哪里定义了CustomSectionName)。可能值得在此处添加检查,以确保您实际返回预期的部分。

在 CustomConfigurationSection 的构造函数中设置静态属性也是值得的:

public sealed class CustomConfigurationSection : ConfigurationSection
{
    public CustomConfigurationSection() {
        Current = CurrentConfiguration.GetSection(CustomSectionName);
    }
    public static CustomConfigurationSection Current { get; private set; }
}