我们在IIS7上运行一个ASP.Net Web应用程序,与WCF Web服务进行通信,该服务处理来自此Web应用程序的请求.
经过一段时间的工作(可能是一周或几天),WCF Web服务开始无法读取其web.config文件中的设置,记录了以下异常:
System.NullReferenceException
ABC.Communication.DataContract.RefreshRequest System.NullReferenceException: Object reference not set to an instance of an object.
at System.Xml.XmlNode.RemoveChild(XmlNode oldChild)
at System.Xml.XmlNode.RemoveAll()
at System.Xml.XmlElement.set_InnerXml(String value)
at System.Configuration.LocalFileSettingsProvider.XmlEscaper.Unescape(String escapedString)
at System.Configuration.LocalFileSettingsProvider.GetPropertyValues(SettingsContext context, SettingsPropertyCollection properties)
at System.Configuration.SettingsBase.GetPropertiesFromProvider(SettingsProvider provider)
at System.Configuration.SettingsBase.GetPropertyValueByName(String propertyName)
at System.Configuration.SettingsBase.get_Item(String propertyName)
at System.Configuration.ApplicationSettingsBase.GetPropertyValue(String propertyName)
at System.Configuration.ApplicationSettingsBase.get_Item(String propertyName)
at ABC.Communication.DataContract.Request.ValidateIpAddress() in C:\Project\ABC.Server\ABC.Communication\DataContract\Request.Validation.cs:line 955
at ABC.Communication.DataContract.RefreshRequestBase.Validate() in C:\Project\ABC.Server\ABC.Communication\DataContract\RefreshRequestBase.cs:line 46
at ABC.Communication.DataContract.RefreshRequest.Validate() in C:\Project\ABC.Server\ABC.Communication\DataContract\RefreshRequest.cs:line 30
at ABC.Communication.ClientCommunicationService.HandleRequest(Request request) in C:\Project\ABC.Server\ABC.Communication\ClientCommunicationService.cs:line 116
或System.ArgumentException
ABC.Communication.DataContract.RefreshRequest System.ArgumentException: The node to be removed is not a child of this node.
at System.Xml.XmlNode.RemoveChild(XmlNode oldChild)
at System.Xml.XmlNode.RemoveAll()
at System.Xml.XmlElement.set_InnerXml(String value)
at System.Configuration.LocalFileSettingsProvider.XmlEscaper.Unescape(String escapedString)
at System.Configuration.LocalFileSettingsProvider.GetPropertyValues(SettingsContext context, SettingsPropertyCollection properties)
at System.Configuration.SettingsBase.GetPropertiesFromProvider(SettingsProvider provider)
at System.Configuration.SettingsBase.GetPropertyValueByName(String propertyName)
at System.Configuration.SettingsBase.get_Item(String propertyName)
at System.Configuration.ApplicationSettingsBase.GetPropertyValue(String propertyName)
at System.Configuration.ApplicationSettingsBase.get_Item(String propertyName)
at ABC.Communication.DataContract.Request.ValidateIpAddress() in C:\Project\ABC.Server\ABC.Communication\DataContract\Request.Validation.cs:line 955
at ABC.Communication.DataContract.RefreshRequestBase.Validate() in C:\Project\ABC.Server\ABC.Communication\DataContract\RefreshRequestBase.cs:line 46
at ABC.Communication.DataContract.DataContracts.RefreshRequest.Validate() in C:\Project\ABC.Server\ABC.Communication\DataContract\RefreshRequest.cs:line 30
at ABC.Communication.ClientCommunicationService.HandleRequest(Request request) in C:\Project\ABC.Server\ABC.Communication\ClientCommunicationService.cs:line 116
或System.Configuration.SettingsPropertyNotFoundException:
ABC.Communication.DataContract.RefreshRequest System.Configuration.SettingsPropertyNotFoundException: The settings property 'ValidateIpConnections' was not found.
at System.Configuration.SettingsBase.GetPropertyValueByName(String propertyName)
at System.Configuration.SettingsBase.get_Item(String propertyName)
at System.Configuration.ApplicationSettingsBase.GetPropertyValue(String propertyName)
at System.Configuration.ApplicationSettingsBase.get_Item(String propertyName)
at ABC.Communication.DataContract.Request.ValidateIpAddress() in C:\Project\ABC.Server\ABC.Communication\DataContract\Request.Validation.cs:line 955
at ABC.Communication.DataContract.RefreshRequestBase.Validate() in C:\Project\ABC.Server\ABC.Communication\DataContract\RefreshRequestBase.cs:line 46
at ABC.Communication.DataContract.RefreshRequest.Validate() in C:\Project\ABC.Server\ABC.Communication\DataContract\RefreshRequest.cs:line 30
at ABC.Communication.ClientCommunicationService.HandleRequest(Request request) in C:\Project\ABC.Server\ABC.Communication\ClientCommunicationService.cs:line 116
抛出此异常的代码非常简单:
private void ValidateIpAddress() {
// Load custom settings
CustomSettings settings = GetCustomSettings();
if (!settings.ValidateIpConnections) // here the exception is thrown!
return;
// the rest of code never reached...
}
现在,在顶级父类Request中实现对自定义设置实例的访问,如下所示:
public abstract partial class Request
{
/// <summary>
/// Custom settings.
/// </summary>
private static readonly CustomSettings customSettings;
/// <summary>
/// .cctor().
/// </summary>
static Request()
{
customSettings = new CustomSettings();
}
/// <summary>
/// Get custom settings.
/// </summary>
/// <returns>Custom settings.</returns>
internal static CustomSettings GetCustomSettings()
{
return customSettings;
}
// ....
}
问题不仅发生在此特定设置ValidateIpConnections,还发生在WCF服务的web.config文件中的其他设置.
目前尚不清楚这种问题的原因是什么,它不能经常和稳定地再现.它似乎并不直接取决于负载/用户数/开放会话数.有时网站运行平稳数周,然后问题每周发生一次,然后连续几天发生.可能,它与应用程序池中的某些工作进程的回收有关.
我们曾经在Windows Server 2003(IIS 6.0)上遇到过它,现在可以在带有IIS 7.0的Windows Server 2008上使用它,因此它似乎与IIS的版本没有直接关系.
我怀疑通过只有初始化一次的所有子类的Request的readonly静态成员共享对CustomSettings类实例的访问可能存在问题.
任何帮助/建议将不胜感激.
最佳答案 我认为您可以避免使用自定义设置类,因为web.config在第一次访问时被缓存.看到
ASP.NET: Where/how is web.config cached?
因此,没有必要进行自己的缓存,然后你可以排除这一点.
我们在其中一台生产服务器上遇到了类似的问题,结果发现病毒扫描程序正在扫描web.config文件,导致应用程序池回收.
我会推荐
>删除静态类并直接使用.net配置类
>调整病毒扫描程序,使其不扫描应用程序所在的文件夹
>在异常发生的时候查看事件日志,看看是否还有其他奇怪的事情发生
>设置asp.net监控(ASP.NET计数器>应用程序重启):http://msdn.microsoft.com/en-us/library/ms972959.aspx和http://blogs.msdn.com/b/johan/archive/2008/02/18/monitoring-application-pool-and-application-restarts.aspx