首页 > 学院 > 开发设计 > 正文

今天,你Try-Catch了吗?

2019-11-17 03:12:45
字体:
来源:转载
供稿:网友

今天,你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 = 0;    w.Start();    for (int i = 0; i < 10000000; i++)    {        try        {            d = Math.Sin(1);        }        catch (Exception ex)        {            Console.WriteLine(ex.ToString());        }    }    w.Stop();    Console.WriteLine(w.Elapsed);    w.Reset();    w.Start();    for (int i = 0; i < 10000000; i++)    {        d = Math.Sin(1);    }    w.Stop();    Console.WriteLine(w.Elapsed);}Output:00:00:00.4269033  // with try/catch00:00:00.4260383  // without.

  

  这个实例说明了并不像有的人说的那样,try catch并不会影响代码的执行效率。但是注意,上面这个实例catch块里并没有rethrow;继续看下面这个示例:

PRivate void TryCatchPerformance(){  int iterations = 100000000;  Stopwatch stopwatch = Stopwatch.StartNew();  int c = 0;  for (int i = 0; i < iterations; i++)  {      try       {           // c += i * (2 * (int)Math.Floor((double)i));           c += i * 2;       }       catch (Exception ex)       {           throw;       }   }   stopwatch.Stop();   WriteLog(String.Format("With try catch: {0}", stopwatch.ElapsedMilliseconds));   Stopwatch stopwatch2 = Stopwatch.StartNew();   int c2 = 0;   for (int i = 0; i < iterations; i++)   {       //  c2 += i * (2 * (int)Math.Floor((double)i));       c2 += i * 2;   }   stopwatch2.Stop();   WriteLog(String.Format("Without try catch: {0}", stopwatch2.ElapsedMilliseconds));}Output:With try catch: 68Without try catch: 34

结果显示好像有影响啊,两倍啊!高兴太早了,把for循环里的计算语句稍微做下改动,变为

c += i * (2 * (int)Math.Floor((double)i));

结果显示为:

Output:With try catch: 640Without try catch: 655

希望破灭了,看来有没有影响还有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;}

正像老板说的:


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表