关于C_Sharp集中处理异常
1.写在前面
“异常意味着什么?”,想必不用对此做多余的解释,我们有理由相信在任何情况下任何应用程序都有可能出现异常,若在程序中没有对异常进行处理,则操作系统会以粗暴的方式处理掉它(弹出错误提示框),在很多应用软件中都可以看到这样的提示框,无疑会影响用户的体验。所以,我们完全有必要对应用程序进行全方位的异常处理,尽可能地覆盖所有可能出现的异常,而程序的异常处理本身是一个非常重要却极易被忽视的问题。
2.一般的异常处理方式
无非就是try...catch...finally...的应用,把所有自认为可能出现异常的代码都用try块wrap起来,没错,这确实是一种完全可行的方法,但却不是最合适的做法。原因如下:
假如需要开发一个WinForm应用程序,首先生成项目时VS自动生成机器代码,然后编码人员进行编码,实现需要的功能,编码人员非常谨慎,所以他在自己编写的代码中添加了若干个异常处理块。。。无论怎么测试都没有出现未被捕获的异常,他很开心,可是有一天运行应用程序时还是发生了异常,这是为什么?答案是编码人员没错,VS生成的机器代码也没错,而是操作系统出错了,在加载该APP时可能遇到了Interruption,进而引发了异常(当然,只是举个例子)
我们可以看到,若撇开系统异常以及RunTimeException不讲,编码人员做得非常好,这样的做法是值得我们学习的,也必须养成这样的习惯。
3.对于一般异常处理的建议
在上面介绍的一般的异常处理方式中,我们不得不需要关注代码臃肿的问题,try...catch...finally...无疑会占用很大篇幅,这个是可以避免的,可以把异常尽量集中处理,推荐的做法是对下层的Exception直接throw出去(在函数定义时添上throws声明即可),在Main函数中统一处理(因为到这里就不能继续throw了,否则。。。)
其次在catch块处理异常时,我们可以新建一个独立的ExceptionClass定义各种异常的处理方法,避免出现大量冗余代码
每个线程都要对应一个异常处理方法,Main属于主线程,在自定义的子线程里应该使用独立的异常处理
4.集中式异常处理
上面的第一条建议只适合控制台应用程序,不存在复杂的人机交互,对于WinForm应用程序将不再适用,那么在WinForm应用程序中怎样合理地处理异常?
C Sharp的Application.ThreadException为我们提供了便利,用于处理UI线程异常,AppDomain.CurrentDomain.UnhandledException用于处理非UI线程异常
用法如下:
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//处理未捕获的异常,始终将异常传送到 ThreadException 处理程序
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
//集中处理异常
//订阅ThreadException事件,处理UI线程异常,处理方法为handler1
Application.ThreadException += new ThreadExceptionEventHandler(handler1);
//订阅UnhandledException事件,处理非UI线程异常,处理方法为handler2
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(handler2); Application.Run(new MainForm());
} public static void handler1(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show("哎呀,好像出错了T_T");
Application.Exit();
} public static void handler2(object sender, UnhandledExceptionEventArgs e)
{
MessageBox.Show("哎呀,好像出错了T_T");
Application.Exit();
}
}
特别说明:
1>请注意Main方法里各个语句的顺序,集中异常处理的相关代码必须放在Application.Run();语句之前,否则没有效果
2>以上代码都在program.cs中,因为程序入口Main在这里
3>若对这样的处理方式还存在疑问,可以查看官方文档以及例程序源码http://msdn.microsoft.com/zh-cn/library/system.windows.forms.application.setunhandledexceptionmode.aspx
5.最后的建议(请务必看看)
1>集中式异常处理并不是万能的,不建议过分依赖这样的处理方式
2>集中式异常处理只是最后的一道防线,程序内部仍然应该添加尽可能完善的异常处理
3>任何异常处理都应该包括两个部分,即A.记录异常信息(写入ErrorLog或者发送到作者邮箱等等)B.善后操作(退出APP或者其它补救处理)
关于C_Sharp集中处理异常的更多相关文章
- alias导致virtualenv异常的分析和解法
title: alias导致virtualenv异常的分析和解法 toc: true comments: true date: 2016-06-27 23:40:56 tags: [OS X, ZSH ...
- ASP.NET Core应用的错误处理[2]:DeveloperExceptionPageMiddleware中间件如何呈现“开发者异常页面”
在<ASP.NET Core应用的错误处理[1]:三种呈现错误页面的方式>中,我们通过几个简单的实例演示了如何呈现一个错误页面,这些错误页面的呈现分别由三个对应的中间件来完成,接下来我们将 ...
- 记一次tomcat线程创建异常调优:unable to create new native thread
测试在进行一次性能测试的时候发现并发300个请求时出现了下面的异常: HTTP Status 500 - Handler processing failed; nested exception is ...
- 使用JSONObject.fromObject的时候出现“There is a cycle in the hierarchy”异常 的解决办法
在使用JSONObject.fromObject的时候,出现“There is a cycle in the hierarchy”异常. 意思是出现了死循环,也就是Model之间有循环包含关系: ...
- SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论
异常汇总:http://www.cnblogs.com/dunitian/p/4523006.html#signalR 后台创建了一个DntHub的集线器 前台在调用的时候出现了问题(经检查是代理对象 ...
- [C#] C# 知识回顾 - 你真的懂异常(Exception)吗?
你真的懂异常(Exception)吗? 目录 异常介绍 异常的特点 怎样使用异常 处理异常的 try-catch-finally 捕获异常的 Catch 块 释放资源的 Finally 块 一.异常介 ...
- [C#] C# 知识回顾 - 学会处理异常
学会处理异常 你可以使用 try 块来对你觉得可能会出现异常的代码进行分区. 其中,与之关联的 catch 块可用于处理任何异常情况. 一个包含代码的 finally 块,无论 try 块中是否在运行 ...
- [C#] C# 知识回顾 - 学会使用异常
学会使用异常 在 C# 中,程序中在运行时出现的错误,会不断在程序中进行传播,这种机制称为“异常”. 异常通常由错误的代码引发,并由能够更正错误的代码进行 catch. 异常可由 .NET 的 CLR ...
- [C#] C# 知识回顾 - 异常介绍
异常介绍 我们平时在写程序时,无意中(或技术不够),而导致程序运行时出现意外(或异常),对于这个问题, C# 有专门的异常处理程序. 异常处理所涉及到的关键字有 try.catch 和 finally ...
随机推荐
- java.lang.Error: Unresolved compilation problem: 解决方案
严重: Allocate exception for servlet WX_Interfacejava.lang.Error: Unresolved compilation problem: The ...
- sqlplus下 查看oracle 执行计划
Microsoft Windows [版本 6.1.7601] 版权所有 (c) Microsoft Corporation.保留所有权利. C:\Users\zhangzheng2 SQL :: C ...
- VS 窗体大小
锁定窗体大小,就是鼠标停在窗口边框的时候,不能拖动来改变它的大小…… 有两种方法: 1.可以把Form的属性 FormborderStyle 后面选择 FixedDialog 2.或者把Form窗体的 ...
- Volley下载图片存放在data/data下 networkImageView lrucache
networkImageView 设置图片的方法 (有效) imageView.setImageUrl("https://www.baidu.com/img/bd_logo1.png&qu ...
- 在Struts2框架中使用OGNL表达式(在jsp页面中使用OGNL表达式)
1. Struts2引入了OGNL表达式,主要是在JSP页面中获取值栈中的值 2. 具体在Struts2中怎么使用呢?如下步骤 * 需要先引入Struts2的标签库(在JSP页面的最上面位置) > ...
- Spring框架的AOP技术之通知类型
1. 通知类型 * @Before -- 前置通知 * @AfterReturing -- 后置通知 * @Around -- 环绕通知(目标对象方法默认不执行的,需要手动执行) * @After - ...
- Algorithmic Trading[z]
Algorithmic Trading has been a hot topic for equity/derivative trading over a decade. Many ibanks an ...
- 深入了解 php 底层机制 (-)洪定坤
- eclipse缓存太重,新手最容易中招
有4种方法,从上到下清理:
- maven 无法下载私服jar包,如刚上传的第三方jar包无法下载。。
原因可能是: 在你下载该文件时 ,的确 私服上没有该文件. 但是maven会在本地仓库建立文件夹路径,并且今天不会再去私服下载. 即使你现在上传3rd jar ,也不会去下载,导致一直找不到jar.. ...