zoukankan      html  css  js  c++  java
  • 类库探源——System.Exception

    一、MSDN描述

    Exception 类: 表示在应用程序执行期间发生的错误

    命名空间 : System

    程序集:   mscorlib.dll

    继承关系: 


    常用属性(含字段)和方法:

    1. 属性
    Message         描述当前异常的消息
    StackTrace     获取调用堆栈上直接帧的字符串表示形式(说白了就是导致异常的函数调用栈信息)
    Source           获取导致异常的应用程序或对象名称
    TargetSite      获取引发异常的方法

    其中 StackTrace 属性最有用

    2.方法

    ToString        返回当前异常的字符串表示形式(重写Object.ToString())

    备注:

    1.  Exception 的常见用法 try-catch 块(用try包裹待执行的代码,用catch来捕捉待执行代码出现的异常)

    2.  try-catch-finally 块,即使异常发生 finally 也会进,finally中放清理资源的代码

    3.  using语句会自动生成try-finally 的IL

    二、一些建议

    1.不要返回错误码(用返回错误码表示异常是Win32时期的特色,在.NET时代这是不允许的)

    2.要通过抛出异常的方式来报告失败

    3.不要轻易吃掉异常,如果是异常就应该抛出

    4.不要把异常作为业务逻辑分支 

    try
    {
        逻辑A  
    }
    catch
    {
        逻辑B
    }
    
    后续逻辑

    5. 不要让公有成员根据某个选项来决定是否抛出异常

    public Type GetType(string name,bool throwOnError); // 不好的设计

    像上面的API设计通常反映出框架设计者的无力做出决定。一个方法要么成功,要么失败,而失败了就应该抛出异常。框架设计者未能做出决定,这迫使API调用者来决定,但由于调用者并不了解API的实现细节,因此他们更难做出正确的决定

    6.异常的抛出应该选择最具有描述性的一个(如系统没有该异常,考虑自定义一个异常)

    如try 语句块的功能是解析某参数,那么catch 块就应该优先用 ArgumentException (参数异常),最后再用 Exception 来捕获其他异常

    try{}
    catch(ArgumentException ex){}
    catch(Exception ex){}

    7. 用 Try-Parse 模式

    如 DateTime.TryParse 这是综合了性能和异常处理的好东西,比直接 DateTime.Parse 好

    三、使用log4net记录异常信息

    官网:http://logging.apache.org/log4net/

    1. 配置 log4net.config

    <?xml version="1.0" encoding="utf-8"?>
    <log4net>
      <root>
        <level value="ALL" />
        <appender-ref ref="Text" />
      </root>
      <appender name="Text" type="log4net.Appender.RollingFileAppender">
        <param name="File" value="D:log4netDemolog4netDemoApp.log" />
        <param name="AppendToFile" value="true" />
        <param name="MaxSizeRollBackups" value="1000" />
        <param name="MaximumFileSize" value="1024KB" />
        <param name="RollingStyle" value="Size" />
        <param name="StaticLogFileName" value="true" />
        <layout type="log4net.Layout.PatternLayout">
          <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
        </layout>
      </appender>
    </log4net>

    修改上面的 <param name="File" value="D:log4netDemolog4netDemoApp.log" /> 改为你想要的日志存放路径

    注意这个 log4net.config 应该编译输入到程序目录(如:binDebug) 

    2. 在主程序启动类中写如下代码

    private const string c_logConfig = "log4net.config";
            private log4net.ILog _log = log4net.LogManager.GetLogger(typeof(Program));
    
    static void Main(string[] args)
    {
        using (Stream stream = File.OpenRead(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, c_logConfig)))
        {
            XmlConfigurator.Configure(stream);
        }
    。。。
    
    }

    3. 使用

    _log.Info("Start");
    _log.Error("捕捉到异常{0}", ex);

    更多log4net方法,查看API文档

    四、全局异常捕获

    AppDomain.CurrentDomain.UnhandledException

    static void Mian()
    {
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
    }
    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Exception error = (Exception)e.ExceptionObject;
        _log.Error("MyHandler caught : " + error.Message);
    }

    WinForm、WPF、ASP.NET 均有全局异常捕获

    五、多线程中的异常捕获

    错误的捕获方式:

     1 static void ThreadException1()
     2 {
     3     var t = new Thread(() => { throw new Exception("线程抛出异常"); });
     4     try
     5     {
     6         t.Start();
     7     }
     8     catch (Exception ex)
     9     {
    10         // 这样捕获不到线程异常
    11         _log.Error("捕获到线程异常 {0}", ex);
    12     }
    13 }
    View Code

    正确的捕获方式:

     1 static void ThreadException2()
     2 {
     3     var t = new Thread(() =>
     4     {
     5         try
     6         {
     7             throw new Exception("线程抛出异常");
     8         }
     9         catch (Exception ex)
    10         {
    11             _log.Error("捕获到线程异常 {0}", ex);
    12         }
    13     });
    14     t.Start();
    15 }
    View Code

    六、系统事件查看器

    这是一个很有用的功能,估计还有不少同学不知道

    右键计算机(我的电脑) ==> 管理 ==> 计算机管理

    本文代码下载

  • 相关阅读:
    leetcode:Valid Parentheses(有效括号匹配)
    leetcode:Remove Nth Node From End of List (移除从尾部数的第N个节点)
    leetcode:Letter Combinations of a Phone Number(手机号码的字母组合)
    leetcode:4Sums(四个数相加的和)
    leetcode:3Sum Closest
    leetcode:3Sum (三个数的和)
    leetcode:Longest Common Prefix(取最长字符串前缀)
    php数据访问
    PHP 基础知识测试题
    面相对象设计模式
  • 原文地址:https://www.cnblogs.com/Aphasia/p/4155382.html
Copyright © 2011-2022 走看看