引言:
高级语言中的异常处理很好用,对于有可能出错的代码我们用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了吗?的更多相关文章

  1. SQLServer如何添加try catch

    在.net中我们经常用到try catch.不过在sqlserver中我们也可以使用try catch捕捉错误,在这里把语法记录下来和大家分享一下, --构建存储过程CREATE PROCEDURE ...

  2. try...catch..finally

    try..catch..finally try{ 代码块1 }catch(Exception e){ 代码块2 }finally{ 代码块3 } catch是抓取代码块1中的异常 代码块2是出异常后的 ...

  3. C++异常处理:try,catch,throw,finally的用法

    写在前面 所谓异常处理,即让一个程序运行时遇到自己无法处理的错误时抛出一个异常,希望调用者可以发现处理问题. 异常处理的基本思想是简化程序的错误代码,为程序键壮性提供一个标准检测机制. 也许我们已经使 ...

  4. POJ 3278 Catch That Cow(bfs)

    传送门 Catch That Cow Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 80273   Accepted: 25 ...

  5. [c#基础]关于try...catch最常见的笔试题

    引言 在翻看之前总结的常见面试题中,关于try...catch异常处理的还是蛮多了,今天看到这个面试题,也就重新学习一下. try..catch语法 try-catch语句由一个try块后跟一个或多个 ...

  6. 高程(4):执行环境、作用域、上下文执行过程、垃圾收集、try...catch...

    高程三 4.2.4.3 一.执行环境 1.全局执行环境是最外层的执行环境. 2.每个函数都有自己的执行环境,执行函数时,函数环境就会被推入一个当前环境栈中,执行完毕,栈将其环境弹出,把控制器返回给之前 ...

  7. try catch里面try catch嵌套

    try catch里能否内嵌try catch?答案是肯定的.但是等内层try catch出异常之后是个什么执行顺序呢?看下面代码 static void Main(string[] args) { ...

  8. 基础知识《十》java 异常捕捉 ( try catch finally ) 你真的掌握了吗?

    本文转载自  java 异常捕捉 ( try catch finally ) 你真的掌握了吗? 前言:java 中的异常处理机制你真的理解了吗?掌握了吗?catch 体里遇到 return 是怎么处理 ...

  9. java try(){}catch(){}自动资源释放

    从 Java 7 build 105 版本开始,Java 7 的编译器和运行环境支持新的 try-with-resources 语句,称为 ARM 块(Automatic Resource Manag ...

  10. Java throws Exception、try、catch

    throws Exception是方法后面接的 意思是向上级抛出异常 try{}里面的异常会被外面的catch捕捉到 抛出异常是throw new Exception("异常"); ...

随机推荐

  1. Android高效加载大图

    通过BitmapFactory的decode方法设置特定的options缩小图片到指定尺寸 1:通过加载设置了只编码图片边界options的图片,获取原图的尺寸和类型 2:计算图片需要缩小的倍数 3: ...

  2. python第三方库 pip 豆瓣源

    pip install xxx -i http://pypi.douban.com/simple/ xxx 为包名

  3. IIS访问php页面问题,报告404错误

    IIS访问php页面出现问题,所有php页面找不到,显示404页面,html页面可以正常访问. 搜索结果: 方案1: 打开WEB服务扩展,把“所有未知ISAPI扩展”设为允许! 方案2: PHP没有完 ...

  4. Docker镜像的备份和恢复

    备份: docker save -o [tar包真实路径] [镜像名 ] 如:docker save -o /usr/docker_data/mongo-backup.tar mongo   导出: ...

  5. 如何修改wifi为家庭网络

    一不小心手快,把新链接的 wifi 选择成“公用网络”了,使用过程中导致某些应用无法联网,那个恨呐!!! 幸好,咱们可以进行手工更改,哈哈,跟哥一起来操作: 进入”网络与共享中心界面": 选 ...

  6. C语言提高 (1) 第一天 数据类型本质与内存四区

    (物联网的分层的概念 b/s c/s 结构 习惯: 在C语言 0 函数执行成功 <0是错误 >1做一些返回值处理 3 课前准备 工作经验,记录 4 数据类型的本质 数据类型的本质是固定大小 ...

  7. VLC编译

    http://blog.csdn.net/hdh4638/article/details/7602321 1 下载代码 ki.videolan.org/VLC_Source_code git colo ...

  8. 朴素贝叶斯(Naive Bayesian)

    简介 Naive Bayesian算法 也叫朴素贝叶斯算法(或者称为傻瓜式贝叶斯分类) 朴素(傻瓜):特征条件独立假设 贝叶斯:基于贝叶斯定理 这个算法确实十分朴素(傻瓜),属于监督学习,它是一个常用 ...

  9. php 返回某个月的 每周几有几天

    不得不承认,这真是一个奇葩的需求,无奈写个类凑活用用. 输入日期格式或者 时间戳,返回当月有多少个周一.周二.周三.....周日; 思路就是 找到这个月有多少天,在便利判断. 稍微考虑下闰年的情况 前 ...

  10. 数据库-mongodb-常用命令

    展示当前集合列表 1 show dbs 查看查询命令 1 db.stu.find().explain(); 结果中的 "cursor":"BasicCursor" ...