我有一个使用C#.NET构建的网站,经常会从各种用户控件产生相当稳定的SQL超时,并且我想轻松地添加一些代码来捕获所有未处理的异常并将它们发送到可以记录它们并向用户显示友好消息的某个位置。
如何通过最小的努力捕获所有未处理的异常?
这个问题似乎说这是不可能的,但这对我来说没有意义(而且它是关于在Windows应用程序中使用.NET 1.1的):
我有一个使用C#.NET构建的网站,经常会从各种用户控件产生相当稳定的SQL超时,并且我想轻松地添加一些代码来捕获所有未处理的异常并将它们发送到可以记录它们并向用户显示友好消息的某个位置。
如何通过最小的努力捕获所有未处理的异常?
这个问题似乎说这是不可能的,但这对我来说没有意义(而且它是关于在Windows应用程序中使用.NET 1.1的):
所有未处理的异常最终都会通过 global.asax 中的 Application_Error 进行传递。因此,要提供一般性的异常消息或进行日志记录操作,请参见 Application_Error。
<customErrors mode="Off"/>
。如果没有这个条目,它在生产服务器上无法正常工作。 - ghord如果您需要在所有线程中捕获异常,最好的方法是实现UnhandledExceptionModule并将其添加到您的应用程序,请查看此处示例。
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
log4net.ILog log = log4net.LogManager.GetLogger(typeof(object));
using (log4net.NDC.Push(this.User.Identity.Name))
{
log.Fatal("Unhandled Exception", Server.GetLastError());
}
}
不要过多关注log4net的内容,Server.GetLastError()是最有用的部分,但是记录详细信息可以按照您喜欢的方式进行。
ELMAH项目听起来值得一试,其特性包括:
ELMAH (Error Logging Modules and Handlers)是一个应用程序范围内完全可插拔的错误日志记录设施。可以动态地将它添加到正在运行的ASP.NET Web应用程序,甚至是机器上的所有ASP.NET Web应用程序中,而无需重新编译或重新部署。
- 记录几乎所有未处理的异常。
- 远程查看记录的异常的全部日志的Web页面。
- 远程查看任何一个已记录异常的详细信息的Web页面。
- 在许多情况下,即使customErrors模式关闭,也可以查看由ASP.NET为给定异常生成的原始黄屏。
- 每次错误发生时都会收到电子邮件通知。
- 日志中最后15个错误的RSS源。
- 多种日志基础存储实现。
有关使用ELMAH的更多信息,请参见dotnetslackers
AppDomain.CurrentDomain.UnhandledException
事件。需要注意的是,你不应该捕获未处理的异常。如果你遇到了 SQL 超时问题,应该专门捕获这些异常。
throw
语句吗? - Kelly Elton您的意思是处理所有线程,包括由第三方代码创建的线程吗?在“已知”的线程中,只需在堆栈顶部捕获 Exception
。
如果使用 .net 2.0 框架,我会使用内置的 Health Monitoring 服务。这里有一篇很好的文章描述了这种方法:https://web.archive.org/web/20210305134220/https://aspnet.4guysfromrolla.com/articles/031407-1.aspx
如果你被限制在 1.0 框架上,我建议使用 ELMAH:http://msdn.microsoft.com/en-us/library/aa479332.aspx
希望这能帮到你。
这个问题有两个部分,处理和识别。
识别
当异常最终被捕获时,这就是你所做的事情,不一定是它抛出的地方。因此,在那个阶段,异常必须具有足够的上下文信息,以便您可以确定问题所在。
处理
对于处理,您可以:
a) 添加一个 HttpModeule。请参见http://www.eggheadcafe.com/articles/20060305.asp。我建议仅在绝对没有上下文信息可用且可能存在 IIS/aspnet 问题的灾难性情况下采用此方法。
b) 创建一个名为 AbstractBasePage 的抽象类,该类派生自 Page 类,并使所有代码后台类都派生自 AbstractBasePage。
AbstractBasePage 可以实现 Page.Error 委托,以便可以在此处捕获(并可能记录)通过 n 层架构上升的所有异常。
我建议针对你所谈论的异常类型(如SQLException),有足够的上下文信息可以让你识别它是一个超时,并采取可能的行动。这些行动可能包括将用户重定向到具有适当消息的自定义错误页面,以处理每种不同类型的异常(如Sql、Web服务、异步调用超时等)。