IIS 6.0上的ASP.NET处理突然停止
我们在一个web应用程序上发现了一个相当奇怪的行为。在本地开发人员工作站上调试时,使用Cassini Development Web服务器可以很好地处理所有内容。当使用IIS 6.0在远程Web服务器上发布时,处理运行大约4或5分钟,然后突然停止 稍后我将解释“突然死亡”意味着什么,首先我想摘录一下失败的代码IIS 6.0上的ASP.NET处理突然停止,asp.net,iis-6,nullreferenceexception,Asp.net,Iis 6,Nullreferenceexception,我们在一个web应用程序上发现了一个相当奇怪的行为。在本地开发人员工作站上调试时,使用Cassini Development Web服务器可以很好地处理所有内容。当使用IIS 6.0在远程Web服务器上发布时,处理运行大约4或5分钟,然后突然停止 稍后我将解释“突然死亡”意味着什么,首先我想摘录一下失败的代码 // loads data from SAP Webservice and serializes it into database LoadXMLDataFromSAP(); /
// loads data from SAP Webservice and serializes it into database
LoadXMLDataFromSAP();
// loop each item of a certain structure and parse data
foreach (var xItem in xSapData)
{
// method determining a status, about 30 LOC, fast execution
GetStatusCodeForContract(xItem);
...
// methods to parse data blocks, about 400 LOC, slow execution (database etc.)
TimeconsumingParserMethod1(xItem);
TimeconsumingParserMethod2(xItem);
}
这段代码在调试时运行良好,执行大约需要13分钟,这没问题,因为它只在与SAP同步所有数据时发生。在IIS 6.0上对同一SAP数据源运行相同代码时,执行会在4或5分钟后停止
首先,程序在调用TimeconsumingParserMethod1时抛出System.NullReferenceException,在下一个循环中,我们在GetStatusCodeForContract上获得System.NullReferenceException。由于我们在两个调用上使用相同的参数,我认为会抛出NullReferenceException,因为成员xItem为null
服务器配置:
8 Core Intel machine
4 GB of RAM
RequestTimeout = 900 (15 minutes)
Memory usage = unlimited
有人知道IIS 6或类似生产服务器环境中的这种行为吗?我终于找到了问题所在。由于本地testserver上的事件日志存在一些问题,我没有注意到一些IIS异常 问题的根源不是任何超时设置,而是ASP.NET 2.0的AppDomain回收行为。如果在webrequest期间更改了许多文件夹结构,AppDomain将被重新加载,这将导致神秘的NullReferenceExceptions 以下文章帮助我找到了这个问题: 链接下面的代码段是使用的变通方法,它只是禁用子文件夹的文件监视,对web.config的更改和程序集仍然会重新加载AppDomain以进行自动部署
System.Reflection.PropertyInfo p = typeof(System.Web.HttpRuntime).GetProperty("FileChangesMonitor", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
object o = p.GetValue(null, null);
System.Reflection.FieldInfo f = o.GetType().GetField("_dirMonSubdirs", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.IgnoreCase);
object monitor = f.GetValue(o);
System.Reflection.MethodInfo m = monitor.GetType().GetMethod("StopMonitoring", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); m.Invoke(monitor, new object[] { });