zoukankan      html  css  js  c++  java
  • 关于C#异常的处理

    关于异常,从我们一开始写代码的时候就开始伴随着我们,只不过那时还没入门,脑子里并没有产生意识这就是异常。
    异常:程序运行期间发生错误,
    异常对象: 将程序发生的各种错误封装成对象
    曾记得第一次面试的时候,面试官问了我这样的一个拐弯的问题“你平时是怎么解决出现的各种问题”,a:当时心中一惊,看别人的面经也提到了这个问题,没有多想“首先自己找找看哪里出了出的错误,定位到出现错误的位置,看出现了什么异常”。q:那你说说有哪些异常,,产生异常的原因,如何处理的。a:空指针,超出索引异常,en en………当时挺尴尬,问到了异常我却回答这么简单,缺乏思考。
    在实际的工作中,捕获异常,收集分析异常对于解决问题至关重要。

    Exception类分析
    常见的异常类
    异常捕获
    异常处理原则和建议
    SystemException类继承Exception,前者是System命名空间中所有其他异常类的基类,在捕获异常的时候,我首先查看的就是Exception对象信息。Exception重要成员如下图
    这里写图片描述
    1.Message属性:产生异常原因的错误消息

    [__DynamicallyInvokable]
    public virtual string Message
    {
    [__DynamicallyInvokable]
    get
    {
    if (this._message != null)
    {
    return this._message;
    }
    if (this._className == null)
    {
    this._className = this.GetClassName();
    }
    return Environment.GetRuntimeResourceString("Exception_WasThrown", new object[] { this._className });
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Message属性是只读属性,GetRuntimeResourceString是获取运行时资源字符串。返回的字符串是产生异常原因的错误消息或者空字符串。
    2.Data:的其他异常信息的键/值对的集合

    public virtual IDictionary Data {
    get {
    if (_data == null)
    if(IsImmutableAgileException(this)) _data = new EmptyReadOnlyDictionaryInternal();
    else
    _data = new ListDictionaryInternal();
    return _data;
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    3.StackTrace:出现异常之前调用的方法名称和签名

    public static string StackTrace
    {
    [SecuritySafeCritical]
    get
    {
    new EnvironmentPermission(PermissionState.Unrestricted).Demand();
    return GetStackTrace(null, true);
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    4.Source属性:包含生成异常的应用程序或对象的名称
    5.TargetSite属性:引发当前异常的方法
    6.GetBaseException方法 :返回System.Exception,它是所有异常类的“基”类。

    常见的异常类

    异常类型有很多,他们都是继承自SystemException,这些异常类型大概分为以下这几种1.与数组集合有关2.与成员访问有关3.与参数有关4.与算术相关5.IO相关6.当然还有其他的一些异常。
    1.与数组集合有关
    IndexOutOfRangeException类:索引超出范围引发的异常
    ArrayTypeMismatchException类:数组集合存储数据类型不正确引发的异常
    RankException类:处理维数错误引发的异常
    2.IO有关的异常
    与IO相关的异常都继承自IOException类,该类用于处理进行文件输入输出操作时所引发的异常,IOException类的5个直接派生类如下。
    DirectoryNotFoundException类:没有找到指定的目录而引发的异常。
    FileNotFoundException类:没有找到文件而引发的异常。
    EndOfStreamException类:处理已经到达流的末尾而还要继续读数据而引发的异常。
    FileLoadException类:无法加载文件而引发的异常。
    PathTooLongException类:文件名太长而引发的异常。
    3.成员访问有关的异常
    与成员访问相关的异常都继承自MemberAccessException这个类,它继承自SystemException。
    FileAccessException:访问字段成员失败所引发的异常
    MethodAccessException:访问方法成员失败引发异常
    MissingMemberException:成员不存在引发的异常
    4.参数相关的异常
    与参数有关的异常类ArgumentException都继承自SystemException,处理给方法成员传递参数时发生异常
    ArgumentOutOfRangeException:当一个参数不在给定范围内引发的异常
    ArgumentNullException:参数为null(不允许null)的情况下引发的异常
    5…与算术相关
    ArithmeticException异常类用于处理与算术相关的异常,它的相关子类如下
    DivideByZeroException:整数十进制试图除以0引发的异常(被除数不能为0)
    NotFiniteNumberException:浮点数运算中出现无穷大或非负值引发的异常
    6.其他异常
    NullReferenceException:当一个对象没有实例化时并引用引发的异常
    InvalidOperationException:当对方法的调用对象当前状态无效时引发异常
    InvalidCastException:处理类型转换期间引发的异常
    OutOfMemoryException:处理内存不足引发的异常
    StackOverflowException:处理栈溢出引发的错误

    异常捕获
    c#中提供try 和catch块提供了一种结构化的异常处理方案,所有可能出现的异常都必须得到妥善的处理,try catch本身并不会影响系统的性能,在没有发生异常的时候try catch 是不会影响系统性能的。受影响的时候是发生异常的时候。
    关键字 try catch finally。先执行try里面的语句,如果抛出异常就会被catch捕获。无论出不出现异常都会执行finally里面的语句。另外不常用的throw关键字:当问题出现时,程序抛出一个异常。

    class Program
    {
    static void Main(string[] args)
    {
    DivideNumber div = new DivideNumber();
    div.DivideMethod(2, 0);
    Console.ReadKey();
    }
    }
    class DivideNumber
    {
    int result;
    public DivideNumber()
    {
    result = 0;
    }
    public void DivideMethod(int a,int b)
    {
    try
    {
    result = a / b;
    }
    catch (DivideByZeroException e)
    {
    Console.WriteLine("exception,被除数不能为0,e.message:" + e.Message);
    }
    finally {
    Console.WriteLine($"{a}除以{b}的结果是"+result);
    }
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    结果如图:
    这里写图片描述

    异常处理原则和建议
    在实际的开发中,异常到底需要怎么写,还是和系统的稳定性和容错性有一定要求的。

    要捕获具体的异常
    在捕获异常的时候,我们经常习惯性写catch(Exception ex) ,这个并非具体的异常,最好是能具体到ArgumentException、FormatException等异常类,不要抛出”new Exception()”
    catch中啥也不干,异常要向顶层抛出
    这种情况在自己写demo的时候可能比较常见,在编写catch(Exception ex)这块代码下啥也不干,不要这样做。切记出现的异常要想顶层抛出
    合理使用finally块
    finally关键字是不管抛出什么类型异常都会被执行,大多数的时候能在finally块下执行的代码,也能写在catch里面。那么finally关键字到底在什么情况下使用比较合适呢,比如清理资源,关闭流,回复状态等。
    抛出的异常要记录下来
    当然程序中出现的异常并不是所有都要记录下来,有些异常还是记录下来便于分析具体的问题。一些记录日志库 log4net ,EIF……
    不要只记录Exception.Message的值,还需要记录Exception.ToString()
    刚刚前面的例子,我打印的e.Message ,仅仅只是输出“尝试除以0”,提示的错误信息不具体,并不推荐这样做。Tostring方法中包含了stacktrace、内部异常信息、Message……通常这些信息比仅一个Message更重要
    不要将“抛出异常”作为函数执行结果的一种
    “抛出异常”应该向顶层抛出,但是不能作为方法执行结果的一种,方法的结果不能是异常类。
    每个线程要包含一个try/catch块
    创建子线程去执行任务时,主线程不会知道子线程的异常情况,所以每个线程都需要一个try、catch.
    来自“代码思考者“的评论
    之前在做C#项目的项目经理时,我也思考过如何有效地在项目团队中实践异常的处理。
    首先,异常处理应该是系统设计规约的一部分出现在系统设计文档中,而不仅仅是一种技术实现。
    作为设计文档的一部分,异常处理应该着眼于系统容错性和稳定性(正如楼主提到的那样)。然后在根据这个规约,再来具体讨论和选择异常处理中使用的各种技术细则。
    比如,在设计服务时,必须在服务的调用接口处有异常处理,否则客户端传过来的任何有害数据都可能让服务器挂掉。
    比如,对异常的处理在系统的设计中,必须有明确说明,不能随便在哪个模块中处理异常。
    以上是我的个人经验,还望走过的朋友多多交流
    ---------------------
    作者:zhanglinblog
    来源:CSDN
    原文:https://blog.csdn.net/kebi007/article/details/78221083
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    springboot(6)-热部署
    springboot(5)-文件上传
    ubuntu修改tomcat使用的jdk
    jstack使用
    HeapAnalyzer如何使用
    查看linux下tomcat使用的jdk版本
    ubuntu-tomcat安装目录
    vi命令
    211java-jdk安装记录
    linux的java安装目录
  • 原文地址:https://www.cnblogs.com/woxihuadabai/p/11231789.html
Copyright © 2011-2022 走看看