今天,你Try-Catch了吗?
引言:
高级语言中的异常处理很好用,对于有可能出错的代码我们用Try-Catch包起来,就能保证系统健壮的运行了,但是你的Try-Catch用对了吗?
今天code review的时候,老板给我提了个问题,让我不要用Try-Catch。原话是这样的:
然后我就想,为什么不让try catch啊,如果不try catch程序出错时不就down了吗,用户连出错信息都得不到,这样的系统也太不友好了吧?
然后老板又跟我解释了,原话如下:
老板在西雅图的微软干了10来年,我是还没毕业的菜鸟,对老板说的话自然是不敢贸然怀疑的,于是乖乖改了代码。但是不安分的内心还是驱使我到网上搜了一下,不搜不知道,原来网上对于这个问题早已是讨论了千八百遍。
总结了10几个来自StackOverflow的回答,大致意思如下:
问题一:使用try catch会不会影响程序运行效率?
解释:
static public void Main(string[] args)
{
Stopwatch w = new Stopwatch();
double d = ; w.Start(); for (int i = ; i < ; i++)
{
try
{
d = Math.Sin();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
} w.Stop();
Console.WriteLine(w.Elapsed);
w.Reset();
w.Start(); for (int i = ; i < ; i++)
{
d = Math.Sin();
} w.Stop();
Console.WriteLine(w.Elapsed);
}
Output:
::00.4269033 // with try/catch
::00.4260383 // without.
这个实例说明了并不像有的人说的那样,try catch并不会影响代码的执行效率。但是注意,上面这个实例catch块里并没有rethrow;继续看下面这个示例:
private void TryCatchPerformance()
{
int iterations = ; Stopwatch stopwatch = Stopwatch.StartNew();
int c = ;
for (int i = ; i < iterations; i++)
{
try
{
// c += i * (2 * (int)Math.Floor((double)i));
c += i * ;
}
catch (Exception ex)
{
throw;
}
}
stopwatch.Stop();
WriteLog(String.Format("With try catch: {0}", stopwatch.ElapsedMilliseconds)); Stopwatch stopwatch2 = Stopwatch.StartNew();
int c2 = ;
for (int i = ; i < iterations; i++)
{
// c2 += i * (2 * (int)Math.Floor((double)i));
c2 += i * ;
}
stopwatch2.Stop();
WriteLog(String.Format("Without try catch: {0}", stopwatch2.ElapsedMilliseconds));
}
Output:
With try catch:
Without try catch:
结果显示好像有影响啊,两倍啊!高兴太早了,把for循环里的计算语句稍微做下改动,变为
c += i * ( * (int)Math.Floor((double)i));
结果显示为:
Output:
With try catch:
Without try catch:
希望破灭了,看来有没有影响还有try块里执行的内容有关。但是大量的实验说明影响是很小的。
问题二:既然try-catch不影响效率,那么为什么不提倡像下面这样使用?
public static string SerializeDTO(DTO dto) {
try {
XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
StringWriter sWriter = new StringWriter();
xmlSer.Serialize(sWriter, dto);
return sWriter.ToString();
} catch(Exception ex) {
throw ex;
}
}
解释:
首先要讲一个问题:如果这段代码的try块里出了问题,那么程序是要down掉的,因为在catch块里throw了Exception,并没有消化掉,如果去掉这个throw 那么在try块出问题的情况下程序也不会down掉了。像下面这样:
public static string SerializeDTO(DTO dto) {
try {
XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
StringWriter sWriter = new StringWriter();
xmlSer.Serialize(sWriter, dto);
return sWriter.ToString();
} catch(Exception ex) {
}
}
虽然这样写程序不会down掉,但有意思的是:这种写法也不推荐。
第一种写法不推荐的原因如下:
try块里抛出的异常信息(有可能是SqlException之类的)被catch块包装成了Exception重新抛出,屏蔽掉了原本的出错信息,在fix bug的时候不好找原因。
第二种写法不推荐的原因如下:
这种写法程序不会down掉,因为catch块把出错信息消化掉了。这样有很不好的后果是:debug的时候找不到真正的错误源头在哪里!!
问题三:提倡的写法是什么?
答案:
try { ... }
catch { throw; }
但是这样写和不用try-catch有什么不同么?根本没有!所以通常的做法是如果需要log出错信息时,才使用try-catch,像下面这样写:
try
{
// code that may throw exceptions
}
catch
{
// add error logging here
throw;
}
正像老板说的:
今天,你Try-Catch了吗?的更多相关文章
- SQLServer如何添加try catch
在.net中我们经常用到try catch.不过在sqlserver中我们也可以使用try catch捕捉错误,在这里把语法记录下来和大家分享一下, --构建存储过程CREATE PROCEDURE ...
- try...catch..finally
try..catch..finally try{ 代码块1 }catch(Exception e){ 代码块2 }finally{ 代码块3 } catch是抓取代码块1中的异常 代码块2是出异常后的 ...
- C++异常处理:try,catch,throw,finally的用法
写在前面 所谓异常处理,即让一个程序运行时遇到自己无法处理的错误时抛出一个异常,希望调用者可以发现处理问题. 异常处理的基本思想是简化程序的错误代码,为程序键壮性提供一个标准检测机制. 也许我们已经使 ...
- POJ 3278 Catch That Cow(bfs)
传送门 Catch That Cow Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 80273 Accepted: 25 ...
- [c#基础]关于try...catch最常见的笔试题
引言 在翻看之前总结的常见面试题中,关于try...catch异常处理的还是蛮多了,今天看到这个面试题,也就重新学习一下. try..catch语法 try-catch语句由一个try块后跟一个或多个 ...
- 高程(4):执行环境、作用域、上下文执行过程、垃圾收集、try...catch...
高程三 4.2.4.3 一.执行环境 1.全局执行环境是最外层的执行环境. 2.每个函数都有自己的执行环境,执行函数时,函数环境就会被推入一个当前环境栈中,执行完毕,栈将其环境弹出,把控制器返回给之前 ...
- try catch里面try catch嵌套
try catch里能否内嵌try catch?答案是肯定的.但是等内层try catch出异常之后是个什么执行顺序呢?看下面代码 static void Main(string[] args) { ...
- 基础知识《十》java 异常捕捉 ( try catch finally ) 你真的掌握了吗?
本文转载自 java 异常捕捉 ( try catch finally ) 你真的掌握了吗? 前言:java 中的异常处理机制你真的理解了吗?掌握了吗?catch 体里遇到 return 是怎么处理 ...
- java try(){}catch(){}自动资源释放
从 Java 7 build 105 版本开始,Java 7 的编译器和运行环境支持新的 try-with-resources 语句,称为 ARM 块(Automatic Resource Manag ...
- Java throws Exception、try、catch
throws Exception是方法后面接的 意思是向上级抛出异常 try{}里面的异常会被外面的catch捕捉到 抛出异常是throw new Exception("异常"); ...
随机推荐
- 目录处理文件&链接命令
一.目录处理文件 1.删除文件或目录 rm -rf [文件或目录] //remove:删除文件或目录 -r:删除目录 -f:强制 2.复制文件或目录 cp [选项] [原文件或 ...
- 关于layui 三级联动 渲染报错解决方法
/** * 时间:2016年11月27日 * 作者:707200833 * 说明:依赖与jQuery和layui, 是基于layui开发的一个省市区联动的小插件, 使用上要基于layui的表单进行使用 ...
- Mysql5.7安装过程----win10
---恢复内容开始--- 1.Mysql官网:https://www.mysql.com/downloads/ 有两种下载方式:msi和zip压缩包 2.我下载的是zip压缩包,选择mysql com ...
- tsar源码分析
从modules/mod_cpu.c入手 ./devel/tsar.h module 结构体: struct module { char name[LEN_32]; char opt_line[LEN ...
- win10卸载瑞星
下载了一个软件,没有注意就不小心装上了瑞星这个流氓软件 百度N种办法并不能解决~ 我试过正常卸载.试过WIN自带卸载.试过重装再卸载 最后采取最傻瓜最暴力的办法 ctrl+alt+delete 打开任 ...
- xx-net安装配置
同学们,有没有因为不会FQ而痛苦?本小白就蛋疼了很久,今天终于把xx-netFQ工具给配置好了,拿出来和大家分享下. 首先,需要先下载xx-net,地址为:https://github.com/XX- ...
- Django入门--模板变量、过滤器及静态文件
一.模板变量 我们登录页面后,在页面上会显示姓名等信息,姓名就是模板变量,用来显示登陆者的名字,Django对这些数据进行处理后,返回给前端页面,前端页面进行渲染. 1.模板变量语法规则 1)在htm ...
- 《你又怎么了我错了行了吧》【Alpha】Scrum meeting 3
第三天 日期:2019/6/16 前言: 第3次会议在女生宿舍召开 讨论了项目功能改进问题,继续代码完善和安排 1.1 今日完成任务情况以及明天任务安排 姓名 当前阶段任务 下一阶段任务 刘 佳 对已 ...
- 提高生产力:SpringMVC中,使用扩展数据类型TypedMap接收Web请求参数
在Web项目中,如果前端MVC框架使用的是SpringMVC,可以使用Map接收前端请求参数,比bean要方便很多. 尤其是SpringMVC和Mybatis一起用的时候,用Map大大减少了需要的be ...
- 出现$ref的原因及解决方案
$ref的产生原因 (1)重复引用:一个集合/对象中的多个元素/属性都引用了同一个对象 (2)循环引用:集合/对象中的多个元素/属性在相互引用导致循环 针对fastjson的处理 fastjson作为 ...