Gor*_*ger 23 iis-7 exception application-pool
我已经阅读了ASP.NET应用程序池关闭问题和IIS 7.5的帖子:应用程序池的问题,但他们没有回答我的问题.
我有一个C#ASP.NET页面,在代码隐藏中实例化一个来自通过BIN目录提供的DLL的类,然后在这个实例上调用一个方法.DLL中的方法System.ArgumentException由于DataRow对象中的非现有列而抛出.事件日志显示以下错误:
Source: ASP.NET 2.0.50727.0
Application ID: /LM/W3SVC/1/ROOT/...
Process ID: 9476
Exception: System.ArgumentException
Message: Column 'someColumn' does not belong to table.
StrackTrace:
Run Code Online (Sandbox Code Playgroud)
ASP.NET页面中的调用代码将方法调用包装在通用try-catch块中.当我请求页面时,这会崩溃我的IIS实例的相应应用程序池,并且我的网站不再可用(错误503).我手动必须重新启动应用程序池,然后该站点再次运行.
根据请求更新try catch ASP.NET代码后面的块:
try
{
SomeExternalClass someExternalClass = new SomeExternalClass();
someExternalClass.SomeMethod( someId );
}
catch( Exception ex )
{
// "smp" is an instance of "StatusMessagePanel", a control we use on all pages
// to show error information, basically a div container with an icon.
smp.ShowError( ex.Message );
}
Run Code Online (Sandbox Code Playgroud)
现在我的问题是为什么一个相对"简单"的异常,例如System.ArgumentException在尝试访问非现有DataRow列时被抛出,会导致整个网站崩溃?try-catchASP.NET页面的通用块也没有帮助,这也不是完全使整个网站不可用的原因,还是错误的假设?我从来没有想过这可以基本上把(II)服务器关闭.
期待有人告诉我在访问之前我应该检查列的存在:我知道这一点,遗留代码现在已经改变了,但这不是我上面所描述的问题,我想知道为什么后果是如此激烈.
更新2
在DLL内部调用的方法会启动一个包含在try-catch块中的线程:
[...]
try
{
ThreadStart starter = () => CreateReport(...)
Thread thread = new Thread( starter );
thread.Start();
if( !thread.Join( TimeSpan.FromMinutes( 15 ) ) )
{
// Log some timeout warning
}
else
{
// Log information about successful report generation
}
}
catch( Exception ex )
{
// Log error information
}
Run Code Online (Sandbox Code Playgroud)
Zac*_*tes 19
正如您在链接问题中所述,很可能IIS的快速失败保护功能会自动关闭您的应用程序池.如果检查事件日志,则可能会快速连续抛出多个未处理的异常.
简单地说,在可配置的时间范围内有足够的未处理异常(默认值为5分钟内为5)将关闭AppPool,导致503 Service Unavailable响应.
此功能背后的原因是,如果您有一个错误的应用程序,您可能不希望它在每个后续请求中自动重新启动,消耗资源并可能损坏数据.
我必须承认,这不是我所期望的"默认"行为.
查看Rick Stahls的解释,它有点深入.
要真正解决这个问题,您需要捕获异常,或者防止异常被抛出(如@leppie建议的那样).未处理的异常应该拆除整个执行过程(意味着单个请求/工作进程,而不是IIS) - 它使.Net代码更容易调试,因为它不会隐藏错误或只是挂起应用程序.
请注意,这在.Net 2.0中已更改:
http://msdn.microsoft.com/en-us/library/ms228965.aspx
http://support.microsoft.com/kb/911816
更新
根据您的上述更新,我认为您的异常实际上并未被捕获,如果它被抛出CreateReport().该方法在单独的线程上执行:

CreateReport()如果还没有一个,你需要一个try-catch :
public static void CreateReport() {
try {
throw new Exception("reducto");
} catch {
Console.WriteLine("done did.");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
32790 次 |
| 最近记录: |