关于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
版权声明:本文为博主原创文章,转载请附上博文链接!
关于C#异常的处理的更多相关文章
- alias导致virtualenv异常的分析和解法
title: alias导致virtualenv异常的分析和解法 toc: true comments: true date: 2016-06-27 23:40:56 tags: [OS X, ZSH ...
- ASP.NET Core应用的错误处理[2]:DeveloperExceptionPageMiddleware中间件如何呈现“开发者异常页面”
在<ASP.NET Core应用的错误处理[1]:三种呈现错误页面的方式>中,我们通过几个简单的实例演示了如何呈现一个错误页面,这些错误页面的呈现分别由三个对应的中间件来完成,接下来我们将 ...
- 记一次tomcat线程创建异常调优:unable to create new native thread
测试在进行一次性能测试的时候发现并发300个请求时出现了下面的异常: HTTP Status 500 - Handler processing failed; nested exception is ...
- 使用JSONObject.fromObject的时候出现“There is a cycle in the hierarchy”异常 的解决办法
在使用JSONObject.fromObject的时候,出现“There is a cycle in the hierarchy”异常. 意思是出现了死循环,也就是Model之间有循环包含关系: ...
- SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论
异常汇总:http://www.cnblogs.com/dunitian/p/4523006.html#signalR 后台创建了一个DntHub的集线器 前台在调用的时候出现了问题(经检查是代理对象 ...
- [C#] C# 知识回顾 - 你真的懂异常(Exception)吗?
你真的懂异常(Exception)吗? 目录 异常介绍 异常的特点 怎样使用异常 处理异常的 try-catch-finally 捕获异常的 Catch 块 释放资源的 Finally 块 一.异常介 ...
- [C#] C# 知识回顾 - 学会处理异常
学会处理异常 你可以使用 try 块来对你觉得可能会出现异常的代码进行分区. 其中,与之关联的 catch 块可用于处理任何异常情况. 一个包含代码的 finally 块,无论 try 块中是否在运行 ...
- [C#] C# 知识回顾 - 学会使用异常
学会使用异常 在 C# 中,程序中在运行时出现的错误,会不断在程序中进行传播,这种机制称为“异常”. 异常通常由错误的代码引发,并由能够更正错误的代码进行 catch. 异常可由 .NET 的 CLR ...
- [C#] C# 知识回顾 - 异常介绍
异常介绍 我们平时在写程序时,无意中(或技术不够),而导致程序运行时出现意外(或异常),对于这个问题, C# 有专门的异常处理程序. 异常处理所涉及到的关键字有 try.catch 和 finally ...
- 基于AOP的MVC拦截异常让代码更优美
与asp.net 打交道很多年,如今天微软的优秀框架越来越多,其中微软在基于mvc的思想架构,也推出了自己的一套asp.net mvc 框架,如果你亲身体验过它,会情不自禁的说‘漂亮’.回过头来,‘漂 ...
随机推荐
- Java之Map接口(双列集合)
Map集合概述 现实生活中,我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射.Java提供了专门的集合类用来存放这种对象关系的对 ...
- 推荐几本高质量的Python书籍--附github下载路径
一 为什么要分享? 最近碰到了一些人和事,感触挺大的.就是发现很多类似自己的软件工程师,一旦工作三五年之后,工作中算是一个熟练工,但是进步的脚步突然慢了下来,虽然你在工作中仍旧很努力.到底是什么原因呢 ...
- Springcloud 微服务 高并发(实战1):第1版秒杀
疯狂创客圈 Java 高并发[ 亿级流量聊天室实战]实战系列之15 [博客园总入口 ] 前言 前言 疯狂创客圈(笔者尼恩创建的高并发研习社群)Springcloud 高并发系列文章,将为大家介绍三个版 ...
- jquery 获取元素(父节点,子节点,兄弟节点)
费话不多说,直接上代码jquery 获取元素 $("#test1").parent(); // 父节点 $("#test1").parents(); // 全部 ...
- 软件测试价值提升之路- 第二章"价值实现的起点"读书笔记
价值实现的起点 2.1 打破常规 打破哪些已经不适应现在软件开发需要的“准则”,明确需要在什么样的环境下.瞄准什么目标来实现测试的价值 找风险:研发内部测试 测试最基础的是找bug,但需要根据风险找最 ...
- java获取当前年份、月份和日期字符串等
Java获取当前年份.月份和日期是通过Calendar类的实例对象来获取的. 首先创建一个Calendar类的实例对象,Calendar类属于java.util包. Calendar calendar ...
- PAT 1010 Radix 进制转换+二分法
Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 110 be true? The an ...
- java架构之-负载均衡-Ribbon 的使用
一. 什么是负载均衡负载均衡就是分发请求流量到不同的服务器.负载均衡一般分为两种:1. 服务器端负载均衡(nginx) 2. 客户端负载均衡(Ribbon) 二. spring- - cloud- - ...
- PHP给图片加上图片水印和文字水印实例
下面给大家分享一下PHP给图片加上图片水印和文字水印实例,这也是网站经常用到的功能,把代码加上去,调用就很简单了. 核心代码: function imageWaterMark($groundImage ...
- 1-5-JS基础-数组应用及实例应用
array 数组 一般简写arr 格式 var arr [ '第1个','第2个','第3个','第4个' ] 最后一个不要叫逗号 alert(arr.length) 弹出数组长度 4个 alert( ...