异常处理—Exception(二)

在上一篇中"异常处理--Exception(一)"中,跟你们简单介绍了一下Exception,也使你们充分的了解了Exception管理在一个项目中的重要性,那如何在咱们的项目中处理异常呢?由于我从事的是Web开发,因此我只跟你们讨论Web的解决方案,Win的解决方式,还但愿同你们一块儿探讨。html

上一章中咱们了解了异常发生的缘由,同时也说了不存在没有bug的程序,任何网站都会遇到各类各样的问题,不管是大网站仍是小网站都会存在,但大公司和小公司对待异常的态度全然不一样,一个是主动出击,一个是守株待兔,咱们是好的开发者,咱们不能坐以待毙,咱们必须主动出击。好了,废话少说,切入主题。数据库

如今网站通常都采用多层开发,多层开发的时候,咱们应该在哪里处理异常、在抛出异常呢?微软的意见是类库的开发人员尽可能不要处理异常,类库的编写应该按照正常的逻辑去编写,固然也有例外,注意事项能够参见"设计异常解决方案的几点注意事项",好的,按照规范,咱们应该尽可能在高层进行捕捉和处理,那咱们该怎么捕捉,捕捉后怎么处理,捕捉哪些异常呢?虽然微软提供了不少系统异常,可是这些异常只是负责抛出相关的信息,并无为记录下来,或者出现高级异常的时候,及时通知咱们,这样的作法仍是守株待兔,咱们仍是应该主动的对其进行处理。好在微软让咱们能够自由的建立自定义的Exception,最好是设定一个自定义Exception基类,让你的其余自定义Exception都继承这个类,以便从此更好的扩展。抛出异常实际上是性能消耗很大的操做,可是Richer教父说过,抛出异常的性能和你程序的稳定性相比,就变得很是眇小了。因此咱们仍是偏向于稳定性。由于处理异常的性能消耗,只是在异常发生时才产生,因此性能方面的问题,咱们能够忽略了。(或许这话比较拗口,但相比系统的性能,我更趋向于系统的稳定)安全

   

如何建立一个自定义的Exceptionpost

不得不说微软考虑的太周到了,要建立一个自定义的Exception是很是简单的。打开VS,建立一个项目,而后添加一个类,在namespace范围内,输入Exception,而后2TabVS就自定帮您建立一个自定义的Exception了。Exception的相关属性和方法,能够参见MSDN。不过自动建立的Exception都是继承System.Exception的,按照微软当初的设想,自定义的异常应该继承System.ApplicationException (好笑的是,微软本身都没有遵照这个约定)。咱们设定这个做为咱们的Exception基类MyBaseException性能

代码片段:网站

[global::System.Serializable] ui

public class MyBaseException : ApplicationException spa

{ 设计

public MyBaseException() { } 日志

public MyBaseException(string message) : base(message) { }

public MyBaseException(string message, Exception inner) : base(message, inner) { }

protected MyBaseException(

System.Runtime.Serialization.SerializationInfo info,

System.Runtime.Serialization.StreamingContext context)

: base(info, context) { }

}

这就是一个标准的自定义Exception了,至于其它的自定义Exception,应该根据你的项目来进行相关的定义。

在进行其余定义以前,咱们先来想一想,咱们捕捉这些Exception以后咱们须要作些什么?咱们须要知道异常发生的各类信息,因此咱们须要LogLog能方便的让咱们查阅发生的异常及Log的异常信息。Log有不少方式,大概的有如下几种:

文本记录

数据库记录

系统事件记录(Trace

第三方组件(Log4Net

这几种方式各有利弊,能够根据项目的需求进行选择,固然你也能够几种方式合用,好比咱们默认的是文本记录方式,可是在建立Log时发生了System.IOException,咱们就必须选择其余的方式进行Log

Log方式

便捷性

查阅性

安全性

结合性

文本记录

方便

通常

数据库记录

通常

方便

通常

系统事件记录

复杂

复杂

通常

第三方组件

复杂

通常

通常

我列举了几种方式的利弊,你们能够有条件的选择。若是你的项目中已经使用第三方组件记录方式,那我建议您使用它。在我后面的解决方案中,我会利用前2种比较常见的方式相结合。

Log的目的是为咱们开发者提供发生异常的时间、地点、人物、缘由,因此咱们必须尽量的详细地记录,根据一个Exception获取信息的方法:

Data

Source

Dates and Times

DateTime.Now

Source of Exception

Exception.Source

Type of Exception

Object.GetType

Exception Message

Exception.Message

Current Method

Reflection.MethodInfo.GetCurrentMethod

Machine Name

Environment.MachineName or Dns.GetHostName

CurrentIP

Dns.GetHostByName("host").AddressList[0].Address

Call Stack

Exception.StackTrace or Environment.StackTrace

OS Information

Environment.OSVersion

Applcation Domain

AppDomain.FriendlyName

Current Assembly

Reflection.Assembly.GetExecutingAssembly

Root Error Cause

Exception.GetBaseException

Chained Exception

Exception.InnerException

Assembly Version

Included in AssemblyName.FullName

Thread ID

AppDomain.GetCurrentThreadId

Thread User

Threading.Thread.CurrentPrincipal

咱们能够根据上面的表格,构建咱们本身所须要的Log信息。为了便捷的管理,咱们应该采用同一格式,进行Log。这里贴一个我写的信息格式,以供参考:

public static class ExceptionLogFormatHelper

{

public static string ExceptionLogFormatter(Exception ex)

{

StringBuilder sbLog = new StringBuilder("\r\n------------------------------------\r\n");

Exception ochainException = ex;

var currentExceptionIndex = 1;

while (ochainException != null)

{

   

sbLog.Append("\r\nException " + currentExceptionIndex + " )")

.Append("\r\nException Type:" + ochainException.GetType().FullName)

.Append("\r\nException Source:" + ochainException.Source)

.Append("\r\nException Message:" + ochainException.Message)

.Append("\r\nException Date:" + DateTime.Now)

.Append("\r\nEnvironment Stack:" + System.Environment.StackTrace);

ochainException = ochainException.InnerException;

currentExceptionIndex++;

}

sbLog.Append("\r\n------------------------------------\r\n");

return sbLog.ToString();

}

}

你也能够根据你本身想要的信息构建这么一个方法。

这一篇废话多了点,不过仍是有必要了解下。还介绍了自定义异常的建立,日志方式的对比,在下一篇,我将介绍通知、异常处理流程和定义本身的一个MyBaseException

==

相关文章
相关标签/搜索