我已阅读帖子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:
ASP.NET 页面中的调用代码将方法调用包装在一个通用try-catch
块中。当我请求该页面时,这会使我的 IIS 实例的相应应用程序池崩溃,并且我的网站不再可用(错误 503)。我必须手动重新启动应用程序池,并且该站点再次运行。
根据后面的 ASP.NET 代码的要求更新try catch
块:
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 );
}
现在我的问题是,为什么一个相对“简单”的异常(例如System.ArgumentException
在尝试访问不存在的DataRow
列时抛出)会使整个网站崩溃?ASP.NET 页面的通用try-catch
块也没有帮助,这也不应该是使整个网站完全不可用的原因,或者这是一个错误的假设?我从没想过这基本上可以使(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
}