最近,我们在阅读配置文件时遇到了以下生产问题。
对象引用未设置为对象的实例。 (位于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。有时(并不总是!)问题在应用程序池的回收之后发生。如果问题发生,我们必须停止我们的应用程序池并启动我们的应用程序池。回收应用程序池没有帮助,也没有重新启动网站。
配置文件中没有更改任何内容。我们注意到的唯一真正的区别是网站本身有更多的请求。
由于我们首先认为它可能是竞争条件,我们已安排应用程序池在特定时间回收,当我们确定没有请求发送到网站时。
在向此站点发送请求的应用程序关闭之后以及再次启动之前,已选择了回收时间。
应用程序池具有以下配置选项集:
该网站设置了以下选项:
之前有没有人遇到过这个问题?
非常感谢任何帮助!
编辑:
这基本上是自定义配置部分代码中的内容:
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。
答案 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; }
}