zoukankan      html  css  js  c++  java
  • throw ex 和 throw 的区别

    留住异常的堆栈信息【throw ex 和 throw 的区别】

     
    当我们想把框架底层的异常向上抛时(比如从DAL到BLL),例如下面的代码
    try
    {
       
    //提交数据库
    }
    catch (System.Data.SqlClient.SqlException ex)
    {
       
    throw ex;
    }
    finally
    {
       
    //释放资源
    }
    上面代码的的问题在于,会造成CLR重新设置异常抛出的起点,导致我们在查看异常堆栈的时候,无法知道实际抛出异常的最底层的调用。
    所以上面的代码应该使用throw关键字来向上抛出异常。
     
    一个完整的测试示例,诸位可以看看输出的   StackTrace   就明白,各种使用   try-catch-throw   形式的不同点了:

    using   System;
    using   System.Collections.Generic;
    using   System.Text;

    namespace   TryCatchThrowTestConsole
    {
            class   Program
            {
                    static   void   Main(string[]   args)
                    {
                            Tester   tester   =   new   Tester();

                            System.Text.StringBuilder   sb   =   new   System.Text.StringBuilder();

                            /*
                              *   说明
                              *   1.   以下   ThrowEx_   两两成对比较
                              *   2.   ThrowEx7   和   ThrowEx8   演示已知的   throw;   与   throw   ex;   的不同,即后者   CLR   重新设置异常的起点
                              *         位于异常捕获点之上中的调用堆栈信息不会包含在   Exception   的   StackTrace   属性中
                              *   3.   ThrowEx1   和   ThrowEx2   演示本讨论的直接目标:为什么   ThrowEx2   中使用   throw;   堆栈信息也无法包括到   F2_1   这一行,而是直接到   F2_2
                              *   4.   ThrowEx3   和   ThrowEx4   情形同   ThrowEx1   和   ThrowEx2
                              *   5.   ThrowEx5   与   ThrowEx6   效果相同。
                              *   6.   try{//...}catch{throw;},   try{//...}catch(Exception){throw;},   try{//...}catch(Exception   ex){throw;}   三者是等价的
                              */

                            try   {
                                    tester.ThrowEx1();
                            }
                            catch   (Exception   ex)   {
                                    sb.AppendLine( "1 ");
                                    sb.AppendLine(ex.StackTrace);   //   堆栈信息如期到   F1_1
                                    sb.AppendLine();
                            }

                            try   {
                                    tester.ThrowEx2();
                            }
                            catch   (Exception   ex)   {
                                    //   堆栈信息只能到   F2_2,我的疑问是为什么不能到   F2_1
                                    //   ThrowEx2()   与   ThrowEx1()   唯一区别就是   ThrowEx1()   内部还有一个   try-catch-throw                                
                                    sb.AppendLine( "2 ");
                                    sb.AppendLine(ex.StackTrace);  
                                    sb.AppendLine();

                                    //sb.AppendLine( "----------- ");
                                    //sb.AppendLine(System.Environment.StackTrace);
                                    //sb.AppendLine( "----------- ");

                                    System.Diagnostics.StackTrace   st   =   new   System.Diagnostics.StackTrace(ex);
                                    sb.AppendLine( "----------- ");
                                    sb.AppendLine(st.ToString());
                                    sb.AppendLine( "----------- ");
                            }

                            try   {
                                    tester.ThrowEx3();
                            }
                            catch   (Exception   ex)   {
                                    sb.AppendLine( "3 ");
                                    sb.AppendLine(ex.StackTrace);
                                    sb.AppendLine();
                            }

                            try   {
                                    tester.ThrowEx4();
                            }
                            catch   (Exception   ex)   {
                                    sb.AppendLine( "4 ");
                                    sb.AppendLine(ex.StackTrace);
                                    sb.AppendLine();
                            }

                            try   {
                                    tester.ThrowEx5();
                            }
                            catch   (Exception   ex)   {
                                    sb.AppendLine( "5 ");
                                    sb.AppendLine(ex.StackTrace);
                                    sb.AppendLine();
                            }

                            try   {
                                    tester.ThrowEx6();
                            }
                            catch   (Exception   ex)   {
                                    sb.AppendLine( "6 ");
                                    sb.AppendLine(ex.StackTrace);
                                    sb.AppendLine();
                            }

                            try   {
                                    tester.ThrowEx7();
                            }
                            catch   (Exception   ex)   {
                                    sb.AppendLine( "7 ");
                                    sb.AppendLine(ex.StackTrace);
                                    sb.AppendLine();
                            }

                            try   {
                                    tester.ThrowEx8();
                            }
                            catch   (Exception   ex)   {
                                    sb.AppendLine( "8 ");
                                    sb.AppendLine(ex.StackTrace);
                                    sb.AppendLine();
                            }

                            string   result   =   sb.ToString();
                            System.IO.File.WriteAllText( "result.txt ",   result);   //   输出到文件
                            Console.WriteLine(result);   //   输出到控制台

                            Console.Write( "press   any   key   to   exit... ");
                            Console.ReadKey();
                    } 

                    public   class   Tester
                    {
                            public   void   ThrowEx1()
                            {
                                    int   i   =   0,   j   =   0;
                                    int   k   =   i   /   j;   //   F1_1
                            }

                            public   void   ThrowEx2()
                            {
                                    try   {
                                            int   i   =   0,   j   =   0;
                                            int   k   =   i   /   j;   //   F2_1  
                                    }
                                    catch   {   //   这里   try{}catch(DivideByZeroException){throw;},   try{}catch(DivideByZeroException   ex){throw;}   等价
                                            throw;   //   F2_2
                                    }                                
                            }

                            public   void   ThrowEx3()
                            {
                                    throw   new   DivideByZeroException();   //   F3_1
                            }

                            public   void   ThrowEx4()
                            {
                                    try   {
                                            throw   new   DivideByZeroException();   //   F4_1
                                    }
                                    catch   {
                                            throw;   //   F4_2
                                    }
                            }

                            public   void   ThrowEx5()
                            {
                                    ThrowEx1();     //   F5_1
                            }

                            public   void   ThrowEx6()
                            {
                                    try   {
                                            ThrowEx1();   //   F6_1
                                    }
                                    catch   {
                                            throw;   //   F6_2
                                    }
                            }

                            public   void   ThrowEx7()
                            {
                                    try   {
                                            ThrowEx1();   //   F7_1
                                    }
                                    catch   (DivideByZeroException)   {   //   这里与   try{}catch{throw;},   try{}catch((DivideByZeroException   ex){throw;}   等价
                                            throw;   //   F7_2
                                    }
                            }

                            public   void   ThrowEx8()
                            {
                                    try   {
                                            ThrowEx1();   //   F8_1
                                    }
                                    catch   (DivideByZeroException   ex)   {
                                            throw   ex;   //   F8_2
                                    }
                            }
                    }
            }
    }
  • 相关阅读:
    这篇通俗实用的Vlookup函数教程,5分钟就可以包你一学就会
    nginx 常见正则匹配符号表示
    Nginx if 条件判断
    nginx 将请求全部指向到一个页面
    windows10下面部署nginx(解决文件名中文乱码问题)
    二.Nginx反向代理和静态资源服务配置
    Nginx的使用(一)代理静态文件
    使用Nginx反向代理和内容替换模块实现网页内容动态替换功能
    如何让NGINX显示文件夹目录
    Nginx 如何设置反向代理 多服务器,配置区分开来,单独文件保存单个服务器 server 主机名配置,通过 include 实现
  • 原文地址:https://www.cnblogs.com/simbadan/p/1988202.html
Copyright © 2011-2022 走看看