1、程序中使用try catch
对于预知会发生异常的代码段使用try catch主动捕获异常,适用于提示给用户或跳转到错误页面,或者通过其它方式处理异常(日志、通知等)。
1 2 3 4 5 6 7 8 9 10 11 12 |
int i = 10; int j = 0; try { Label1.Text = (i / j).ToString(); } catch (Exception ex) { // 这里处理异常:Redirect、Transfer、Log、Notice等 Console.WriteLine("Page:" + ex.Message); } |
2、Global中使用Application_Error
如果异常在程序中没有被处理(如没有try catch),则异常的处理会流转到这个方法,这里边可以对异常进行处理。但是此方式不能捕捉子线程中的异常。
1 2 3 4 |
int i = 10; int j = 0; Label2.Text = (i / j).ToString(); |
1 2 3 4 5 |
void Application_Error(object sender, EventArgs e) { // 在出现未处理的错误时运行的代码 Server.Transfer("ErrorPage.aspx"); } |
1 2 |
string message = HttpContext.Current.Error != null ? (HttpContext.Current.Error.InnerException != null ? HttpContext.Current.Error.InnerException.Message : string.Empty) : string.Empty; Label1.Text = message; |
3、在web.config中配置
出现错误后跳转到ErrorPage.aspx,和Application_Error类似,采用redirectMode模式可以传递异常到错误页面。
1 2 3 |
<customErrors redirectMode="ResponseRewrite" mode="On" defaultRedirect="~/ErrorPage.aspx"> <error statusCode="500" redirect="~/ErrorPage.aspx"/> </customErrors> |
4、使用FirstChance异常通知。
关联到AppDomain,如果应用程序域内发生异常,则会首先触发这个事件,然后才查找catch块处理异常。不过在这个事件中不能处理异常,不能消灭异常,只是可以按照通知进行处理。因为如果这里处理了异常,catch块就不能进行处理了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
void Application_Start(object sender, EventArgs e) { // 在应用程序启动时运行的代码 AppDomain.CurrentDomain.FirstChanceException += new EventHandler<System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs>(CurrentDomain_FirstChanceException); } void CurrentDomain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e) { Console.WriteLine(e.Exception.Message); // 错误:响应在上下文中不能使用 // Response.Redirect("ErrorPage.aspx"); // 错误:未将对象引用设置到对象的实例 // Server.Transfer("ErrorPage.aspx"); } |
5、绑定UnhandledException事件
关联到AppDomain,关于这个事件并不是每次都能触发,和使用的方式有关,情况比较多。一般情况下我们只能获取这个异常,而不能阻止中断应用程序。
下边给出一个例子:
1 2 3 4 5 6 7 8 9 10 |
void Application_Start(object sender, EventArgs e) { // 在应用程序启动时运行的代码 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); } void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Console.WriteLine(e.Exception.Message); } |
一般的未处理异常都会被Application_Error捕捉到,我们这里在线程中抛出一个异常。
另外StackOverflowException在.net4中不再能被UnhandledException捕捉到。
1 2 3 4 5 6 7 8 9 10 11 |
private void CutString() { //throw (new Exception("Test Unhandled exception")); //throw (new StackOverflowException("Test Unhandled exception")); } protected void Button1_Click(object sender, EventArgs e) { Thread th = new Thread(new ThreadStart(CutString)); th.Start(); } |
更多请参考:
http://msdn.microsoft.com/zh-Cn/library/system.appdomain.unhandledexception.aspx
http://mlichtenberg.wordpress.com/2011/09/19/catching-unhandled-exceptions-in-asp-net/
6、延伸:子线程异常的处理。网上有介绍通过代理在主线程处理子线程的异常,但是在asp.net中是无状态的,主线程有可能很快消失,其中的某些处理可能执行失败。
这里使用Thread.Sleep使主线程不会很快结束。这种异常处理起来很麻烦,不建议在asp.net中使用处理时间很长的线程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
protected void Button1_Click(object sender, EventArgs e) { Thread th = new Thread(new ThreadStart(() => { try { throw (new Exception("Test Unhandled exception")); } catch (Exception ex) { //跳转到错误页面 Response.Redirect("ErrorPage.aspx"); } })); th.Start(); // asp.net主线程会很快结束,这里让他等等页面跳转。 Thread.Sleep(2000); } |
本文列举了处理异常的几种方式,有通过订阅AppDomain事件的方式,有通过配置文件的方式,还有通过Global的方式,最后还对子线程异常的处理谈了一点想法,但是都没有提供一个完善的解决方案,有兴趣的朋友可以自己试试。
关键字: Application_Error customErrors FirstChanceException UnhandledException
发表评论
相关文章
热门标签
.net core activex asp.net Cassandra code first excel Flex GridView iis JAVA jquery jsp mvc mysql PowerDesigner rabbitmq Silverlight VPN webservice WordPress XML 图片滚动 垂直滚动 多线程 导出excel 微信分享 排序算法 插件 界面原型设计 自定义控件文章分类
最新评论