解析Exception和C#处理Exception的常用方法总结
在.NET中,异常是指成员没有完成它的名称宣称可以完成的行动。在异常的机制中,异常和某件事情的发生频率无关。
异常处理四要素包括:一个表示异常详细信息的类类型;一个向调用者引发异常类实例的成员;调用者的一段调用异常成员的代码块;调用者的一段处理将要发生异常的代码块。异常类类型包括:基类:System.Exception;系统级异常:System.SystemException;应用程序级异常:System.ApplicationException。
(一).在.NET中有如下的异常类:
(1).由System.SystemException派生的异常类型:
| System.AccessViolationException | 在试图读写受保护内存时引发的异常。 |
| System.ArgumentException | 在向方法提供的其中一个参数无效时引发的异常。 |
| System.Collections.Generic.KeyNotFoundException | 指定用于访问集合中元素的键与集合中的任何键都不匹配时所引发的异常。 |
| System.IndexOutOfRangeException | 访问数组时,因元素索引超出数组边界而引发的异常。 |
| System.InvalidCastException | 因无效类型转换或显示转换引发的异常。 |
| System.InvalidOperationException | 当方法调用对于对象的当前状态无效时引发的异常。 |
| System.InvalidProgramException | 当程序包含无效Microsoft中间语言(MSIL)或元数据时引发的异常,这通常表示生成程序的编译器中有bug。 |
| System.IO.IOException | 发生I/O错误时引发的异常。 |
| System.NotImplementedException | 在无法实现请求的方法或操作时引发的异常。 |
| System.NullReferenceException | 尝试对空对象引用进行操作时引发的异常。 |
| System.OutOfMemoryException | 没有足够的内存继续执行程序时引发的异常。 |
| System.StackOverflowException | 挂起的方法调用过多而导致执行堆栈溢出时引发的异常。 |
(2).由System.ArgumentException派生的异常类型:
| System.ArgumentNullException | 当将空引用传递给不接受它作为有效参数的方法时引发的异常。 |
| System.ArgumentOutOfRangeException | 当参数值超出调用的方法所定义的允许取值范围时引发的异常。 |
(3).由System.ArithmeticException派生的异常类型:
| System.DivideByZeroException | 试图用零除整数值或十进制数值时引发的异常。 |
| System.NotFiniteNumberException | 当浮点值为正无穷大、负无穷大或非数字(NaN)时引发的异常。 |
| System.OverflowException | 在选中的上下文中所进行的算数运算、类型转换或转换操作导致溢出时引发的异常。 |
(4).由System.IOException派生的异常类型:
| System.IO.DirectoryNotFoundException | 当找不到文件或目录的一部分时所引发的异常。 |
| System.IO.DriveNotFoundException | 当尝试访问的驱动器或共享不可用时引发的异常。 |
| System.IO.EndOfStreamException | 读操作试图超出流的末尾时引发的异常。 |
| System.IO.FileLoadException | 当找到托管程序却不能加载它时引发的异常。 |
| System.IO.FileNotFoundException | 试图访问磁盘上不存在的文件失败时引发的异常。 |
| System.IO.PathTooLongException | 当路径名或文件名超过系统定义的最大长度时引发的异常。 |
(5).其他常用异常类型:
| ArrayTypeMismatchException | 试图在数组中存储错误类型的对象。 |
| BadImageFormatException | 图形的格式错误。 |
| DivideByZeroException | 除零异常。 |
| DllNotFoundException | 找不到引用的dll。 |
| FormatException | 参数格式错误。 |
| MethodAccessException | 试图访问私有或者受保护的方法。 |
| MissingMemberException | 访问一个无效版本的dll。 |
| NotSupportedException | 调用的方法在类中没有实现。 |
| PlatformNotSupportedException | 平台不支持某个特定属性时抛出该错误。 |
(二)..NET的异常处理方式:
发生异常时,系统将搜索可以处理该异常的最近的 catch 子句(根据该异常的运行时类型来确定)。首先,搜索当前的方法以查找一个词法上包含着它的 try 语句,并按顺序考察与该 try 语句相关联的各个 catch 子句。如果上述操作失败,则在调用了当前方法的方法中,搜索在词法上包含着当前方法调用代码位置的 try 语句。此搜索将一直进行下去,直到找到可以处理当前异常的 catch 子句(该子句指定一个异常类,它与当前引发该异常的运行时类型属于同一个类或是该运行时类型所属类的一个基类)。注意,没有指定异常类的 catch 子句可以处理任何异常。
找到匹配的 catch 子句后,系统将把控制转移到该 catch 子句的第一条语句。在 catch 子句的执行开始前,系统将首先按顺序执行嵌套在捕捉到该异常的 try 语句里面的所有 try 语句所对应的全部 finally 子句。
(1).try块:包含的代码通常需要执行一些通用的资源清理操作,或者需要从异常中恢复,或者两者都需要。try块还可以包含也许会抛出异常的代码。
(2).catch块:包含的是响应一个异常需要执行的代码。如果没有任何捕捉类型与抛出的异常匹配,CLR会去调用栈的更高一层搜索一个与异常匹配的捕捉类型。
(3).finally块:包含的代码是保证会执行的代码。finally块所有代码执行完毕后,线程退出finally块,执行紧跟在finally块之后的语句。
(三).Exception的常用属性的源码解析:
(1).Message:包含辅助性文字说明,指出抛出异常的原因。
public virtual String Message {
get {
if (_message == null) {
if (_className==null) {
_className = GetClassName();
}
return Environment.GetRuntimeResourceString("Exception_WasThrown", _className);
} else {
return _message;
}
}
}
(2).Data:对一个“键/值对”集合的引用。
public virtual IDictionary Data {
[System.Security.SecuritySafeCritical] // auto-generated
get {
if (_data == null)
if (IsImmutableAgileException(this))
_data = new EmptyReadOnlyDictionaryInternal();
else
_data = new ListDictionaryInternal();
return _data;
}
}
(3).Source:包含生成异常的程序集名称。
public virtual String Source {
#if FEATURE_CORECLR
[System.Security.SecurityCritical] // auto-generated
#endif
get {
if (_source == null)
{
StackTrace st = new StackTrace(this,true);
if (st.FrameCount>)
{
StackFrame sf = st.GetFrame();
MethodBase method = sf.GetMethod();
Module module = method.Module;
RuntimeModule rtModule = module as RuntimeModule;
if (rtModule == null)
{
System.Reflection.Emit.ModuleBuilder moduleBuilder = module as System.Reflection.Emit.ModuleBuilder;
if (moduleBuilder != null)
rtModule = moduleBuilder.InternalModule;
else
throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeReflectionObject"));
}
_source = rtModule.GetRuntimeAssembly().GetSimpleName();
}
}
return _source;
}
#if FEATURE_CORECLR
[System.Security.SecurityCritical] // auto-generated
#endif
set { _source = value; }
}
(四).异常处理的常用方法:
(1).提取异常及其内部异常堆栈跟踪
/// <summary>
/// 提取异常及其内部异常堆栈跟踪
/// </summary>
/// <param name="exception">提取的例外</param>
/// <param name="lastStackTrace">最后提取的堆栈跟踪(对于递归), String.Empty or null</param>
/// <param name="exCount">提取的堆栈数(对于递归)</param>
/// <returns>Syste.String</returns>
public static string ExtractAllStackTrace(this Exception exception, string lastStackTrace = null, int exCount = )
{
var ex = exception;
const string entryFormat = "#{0}: {1}\r\n{2}";
//修复最后一个堆栈跟踪参数
lastStackTrace = lastStackTrace ?? string.Empty;
//添加异常的堆栈跟踪
lastStackTrace += string.Format(entryFormat, exCount, ex.Message, ex.StackTrace);
if (exception.Data.Count > )
{
lastStackTrace += "\r\n Data: ";
foreach (var item in exception.Data)
{
var entry = (DictionaryEntry)item;
lastStackTrace += string.Format("\r\n\t{0}: {1}", entry.Key, exception.Data[entry.Key]);
}
}
//递归添加内部异常
if ((ex = ex.InnerException) != null)
return ex.ExtractAllStackTrace(string.Format("{0}\r\n\r\n", lastStackTrace), ++exCount);
return lastStackTrace;
}
(2).检查字符串是空的或空的,并抛出一个异常
/// <summary>
/// 检查字符串是空的或空的,并抛出一个异常
/// </summary>
/// <param name="val">值测试</param>
/// <param name="paramName">参数检查名称</param>
public static void CheckNullOrEmpty(string val, string paramName)
{
if (string.IsNullOrEmpty(val))
throw new ArgumentNullException(paramName, "Value can't be null or empty");
}
(3).检查参数不是无效,并抛出一个异常
/// <summary>
/// 检查参数不是无效,并抛出一个异常
/// </summary>
/// <param name="param">检查值</param>
/// <param name="paramName">参数名称</param>
public static void CheckNullParam(object param, string paramName)
{
if (param == null)
throw new ArgumentNullException(paramName, paramName + " can't be null");
}
(4).请检查参数1不同于参数2
/// <summary>
/// 请检查参数1不同于参数2
/// </summary>
/// <param name="param1">值1测试</param>
/// <param name="param1Name">name of value 1</param>
/// <param name="param2">value 2 to test</param>
/// <param name="param2Name">name of vlaue 2</param>
public static void CheckDifferentsParams(object param1, string param1Name, object param2, string param2Name)
{
if (param1 == param2) {
throw new ArgumentException(param1Name + " can't be the same as " + param2Name,
param1Name + " and " + param2Name);
}
}
(5).检查一个整数值是正的(0或更大)
/// <summary>
/// 检查一个整数值是正的(0或更大)
/// </summary>
/// <param name="val">整数测试</param>
public static void PositiveValue(int val)
{
if (val < )
throw new ArgumentException("The value must be greater than or equal to 0.");
}
异常处理器(程序):对于程序中出现的异常,在C#中是使用一种被称为“异常处理器(程序)”的错误捕获机制来进行处理的, 你可以认为异常处理器(程序)就是发生错误时,能够接受并处理错误的接受者和处理。
解析Exception和C#处理Exception的常用方法总结的更多相关文章
- 扩展Exception,增加判断Exception是否为SQL引用约束异常方法!
在设计数据表时,如果将某些列设置为关联其它表的外键,那么如果对其进行增加.修改操作时,其关联表若没有相匹配的记录则报错,或者在对其关联表进行删除时,也会报错,这就是外键约束的作用,当然除了外键还有许多 ...
- HTTP Status 500 - Request processing failed; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement
1.什么操作出现:当我在项目中添加产品或者修改时,浏览器出现HTTP Status 500 - Request processing failed; nested exception is org.h ...
- code is 9998;desc is 插入失败exception is org.hibernate.exception.JDBCConnectionException: Could not op
1.错误描述 [ERROR:]2015-05-05 09:27:12,090 [插入失败] org.hibernate.exception.JDBCConnectionException: Could ...
- org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Cannot open con
org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session f ...
- 报错org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet"
org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n ...
- org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Listener threw exception
RabbitMQ 报出的错! org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException ...
- 【hibernate】报错:org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.DataException: could not execute statement
报错如下: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a ...
- 报错:org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement
org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement; SQL [n ...
- SSISWMI-Watching for the Wql query caused the following system exception: "Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"
将带有WMI WATCH TASK的SSIS包排到sql server agent跑,报异常,这是运行账号权限的问题. Executed as user: sss. Microsoft (R) ...
- SpringBoot保存数据报错:could not execute statement; SQL [n/a]; constraint [PRIMARY];nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
使用SpringBoot做JAVA开发时,用Repository.save();保存数据的时候遇到了报错: could not execute statement; SQL [n/a]; constr ...
随机推荐
- CF2.BC
B. Arpa's obvious problem and Mehrdad's terrible solution time limit per test 1 second memory limit ...
- 使用epel源安装软件
问题:centos提供的官方base源可能无法提供某些软件的安装,可以通过epel源 系统:centos6.5 x86_64 解决:安装epel源 #wget http://dl.fedoraproj ...
- spring xmlns 记录
spring xmlns 命名空间可从: http://www.springframework.org/schema/ 根据需求选择 如: 1.选择 : aop ...
- Apache与Nginx区别
1.nginx相对于apache的优点: 轻量级,同样起web 服务,比apache占用更少的内存及资源 抗并发,nginx 处理请求是异步非阻塞的,而apache 则是阻塞型的,在高并发下nginx ...
- Windows Server 2012 支持的逻辑盘容量最大是多少?
这个问题似乎看起来是问系统支持最大硬盘参数?其实不然,这和文件系统有着很大关系. 磁盘在系统应用之前,要先初始化,然后创建卷,再进行格式化后完成在系统的挂载.完成这些操作之后,磁盘空间可以被系统使用. ...
- c++ eof()函数
C++ eof()函数可以帮助我们用来判断文件是否为空,抑或是判断其是否读到文件结尾.在这里我们将会对其进行详细的介绍. C++编程语言中的很多功能在我们的实际应用中起着非常大的作用.比如在对文件文本 ...
- 初识Opserver,StackExchange的监控解决方案
Opserver是闻名遐迩的网站Stack Overflow的开源监控解决方案,由Stack Exchange发布.它基于.NET框架构建,这在监控工具领域有些与众不同. 旨在为每个受监控系统的健康状 ...
- 写一个脚本,自动启动tomcat
我的服务器是使用tomcat的,时不时tomcat的进程会突然结束掉,不知道为什么,从日志上看也没有任何可疑之处,貌似就这样突然没了,接下来的日志都是重新启动tomcat之后打印的了.原因找不到,但要 ...
- Dash文档制作教程
前言 什么是Dash 面向程序员的文档库(Mac) 代码片段管理工具 这是强烈推荐给每天在各种API文档中摸爬滚打的程序员们的神器. 为什么要自己制作文档 官方的源中没有相关文档 文档在离线下体验更好 ...
- 老司机学新平台 - Xamarin Forms开发框架二探 (Prism vs MvvmCross)
在上一篇Xamarin开发环境及开发框架初探中,曾简单提到MvvmCross这个Xamarin下的开发框架.最近又评估了一些别的,发现老牌Mvvm框架Prism现在也支持Xamarin Forms了, ...