应用程序池回收后,自定义配置部分为空

时间:2014-04-03 07:31:49

标签: c# asp.net .net iis

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

  

对象引用未设置为对象的实例。   (位于C:\ applications \ SampleWebsite \ web.config第105行)   System.Configuration.BaseConfigurationRecord.EvaluateOne(字符串[]   keys,SectionInput输入,Boolean isTrusted,FactoryRecord   factoryRecord,SectionRecord sectionRecord,Object parentResult)at   System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord   factoryRecord,SectionRecord sectionRecord,Object parentResult,   Boolean getLkg,Boolean getRuntimeObject,Object&结果,对象&   resultRuntimeObject)at   System.Configuration.BaseConfigurationRecord.GetSectionRecursive(字符串   configKey,Boolean getLkg,Boolean checkPermission,Boolean   getRuntimeObject,Boolean requestIsHere,Object&结果,对象&   resultRuntimeObject)at   System.Configuration.BaseConfigurationRecord.GetSection(字符串   configKey)   System.Configuration.ConfigurationManager.GetSection(字符串   sectionName)at   SampleWebsite.Configuration.CustomConfigurationSection.get_Current()   在   C:\构建\ 1 \ SampleWebsite \源头\源\ SampleWebsite \配置\ CustomConfigurationSection.cs:线   69点   SampleWebsite.Security.AuthorizationManager.CheckAccess(AuthorizationContext   上下文)   C:\构建\ 1个\ SampleWebsite的\ Sources \来源\ SampleWebsite \安全\ AuthorizationManager.cs:行   161 at   System.IdentityModel.Services.ClaimsPrincipalPermission.Demand()at   System.Security.PermissionSet.DemandNonCAS()at   SampleWebsite.CustomController.Test()in   C:\构建\ 1 \ SampleWebsite \源头\源\ SampleWebsite \控制器\ CustomController.cs:线   125 at lambda_method(Closure,Object,Object [])at   System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor<> C_ DisplayClass13.b _c(对象   instance,Object [] methodParameters)at   System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(对象   instance,Object [] arguments)at   System.Threading.Tasks.TaskHelpers.RunSynchronously [TResult](Func`1   func,CancellationToken cancellationToken)

我们在Windows Server 2012上的IIS 8上使用.NET 4.5。有时(并不总是!)问题在应用程序池的回收之后发生。如果问题发生,我们必须停止我们的应用程序池并启动我们的应用程序池。回收应用程序池没有帮助,也没有重新启动网站。

配置文件中没有更改任何内容。我们注意到的唯一真正的区别是网站本身有更多的请求。

由于我们首先认为它可能是竞争条件,我们已安排应用程序池在特定时间回收,当我们确定没有请求发送到网站时。

在向此站点发送请求的应用程序关闭之后以及再次启动之前,已选择了回收时间。

应用程序池具有以下配置选项集:

  • 自动启动:true
  • 开始模式:AlwaysRunning
  • 立即启动应用程序池:true

该网站设置了以下选项:

  • Preload Enabled:true
  • 自动启动:true

之前有没有人遇到过这个问题?

非常感谢任何帮助!

编辑:

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

public sealed class CustomConfigurationSection : ConfigurationSection
{
    private static CustomConfigurationSection _current;

    public static CustomConfigurationSection Current
    {
        get
        {
            return _current
                ?? (_current = ConfigurationManager.GetSection(CustomSectionName) as CustomConfigurationSection);
        }
    }
}

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

1 个答案:

答案 0 :(得分:2)

您正在使用is not thread safe的空合并运算符。在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; }
}