详谈.NET的异常处理

2019-05-26 01:18:35于海丽

二.DotNET异常的常用处理机制:

在代码发生异常后,我们需要去处理这个异常,如果一个异常没有得到及时的处理,CLR会终止进程。在异常的处理中,我们可以在一个线程捕获异常,在另一个线程中重新抛出异常。异常抛出时,CLR会在调用栈中向上查找与抛出的异常类型匹配的catch块。如果没有任何catch块匹配抛出的异常类型,就发生一个未处理异常。CLR检测到进程中的任何线程有一个位处理异常,都会终止进程。

1.异常处理块:

(1).try块:包含代码通常需要执行一些通用的资源清理操作,或者需要从异常中恢复,或者两者都需要。try块还可以包含也许会抛出异常的代码。一个try块至少有一个关联的catch块或finall块。      

(2).catch块:包含的是响应一个异常需要执行的代码。catch关键字后的圆括号中的表达式是捕获类型。捕获类型从System.Exception或者其派生类指定。CLR自上而下搜素一个匹配的catch块,所以应该教具体的异常放在顶部。一旦CLR找到一个具有匹配捕获类型的catch块,就会执行内层所有finally块中的代码,”内层finally“是指抛出异常的tey块开始,到匹配异常的catch块之间的所有finally块。

使用System.Exception捕捉异常后,可以采用在catch块的末尾重新抛出异常,因为如果我们在捕获Exception异常后,没有及时的处理或者终止程序,这一异常可能对程序造成很大的安全隐患,Exception类是所有异常的基类,可以捕获程序中所有的异常,如果出现较大的异常,我们没有及时的处理,造成的问题是巨大的。

(3).finally块:包含的代码是保证会执行的代码。finally块的所有代码执行完毕后,线程退出finally块,执行紧跟在finally块之后的语句。如果不存在finally块,线程将从最后一个catch块之后的语句开始执行。

备注:异常块可以组合和嵌套,对于三个异常块的样例,在这里就不做介绍,异常的嵌套可以防止在处理异常的时候再次出现未处理的异常,以上这些就不再赘述。

2.异常处理实例:

(1).异常处理扩展方法:

 /// <summary>
 /// 格式化异常消息
 /// </summary>
 /// <param name="e">异常对象</param>
 /// <param name="isHideStackTrace">是否隐藏异常规模信息</param>
 /// <returns>格式化后的异常信息字符串</returns>
 public static string FormatMessage(this Exception e, bool isHideStackTrace = false)
 {
  var sb = new StringBuilder();
  var count = 0;
  var appString = string.Empty;
  while (e != null)
  {
  if (count > 0)
  {
   appString += " ";
  }
  sb.AppendLine(string.Format("{0}异常消息:{1}", appString, e.Message));
  sb.AppendLine(string.Format("{0}异常类型:{1}", appString, e.GetType().FullName));
  sb.AppendLine(string.Format("{0}异常方法:{1}", appString, (e.TargetSite == null ? null : e.TargetSite.Name)));
  sb.AppendLine(string.Format("{0}异常源:{1}", appString, e.Source));
  if (!isHideStackTrace && e.StackTrace != null)
  {
   sb.AppendLine(string.Format("{0}异常堆栈:{1}", appString, e.StackTrace));
  }
  if (e.InnerException != null)
  {
   sb.AppendLine(string.Format("{0}内部异常:", appString));
   count++;
  }
  e = e.InnerException;
  }
  return sb.ToString();
 }