当前位置: 首页 > 编程语言 > C#

n层应用程序中的异常处理?在

时间:2023-04-10 14:50:37 C#

n层应用程序中共享异常处理?在分层应用程序中处理异常的推荐方法或最佳实践是什么?考虑一个简单的例子。假设您有一个调用业务层的UI,业务层调用数据层://UIprotectedvoidButtonClick_GetObject(objectsender,EventArgse){try{MyObjobj=Business.GetObj();}catch(Exceptionex){Logger.Log(ex);//日志应该在这里发生,还是在源头发生?MessageBox.Show("发生错误");}}//业务publicMyObjGetObj(){//这个try/catch块是多余的吗?尝试{MyObjobj=DAL.GetObj();}catch(Exceptionex){thrownewException("ADALExceptionoccurred",ex);}}//DALpublicMyObjGetObj(){//或者这个try/catch块是多余的吗?try{//连接到数据库,获取对象}catch(SqlExceptionex){thrownewException("ASQLExceptionoccurred",ex);您对上述异常处理有何批评?谢谢我的经验法则通常是在顶层捕获异常并在那里记录(或以其他方式报告),因为这是您获得有关错误的最多信息的地方-最重要的是完整的堆栈跟踪。但是,在其他层捕获异常可能有一些原因:异常确实被处理了。例如。连接失败,但层已重试。重新抛出包含更多信息的异常(查看堆栈时尚不可用)。例如。DAL可能会报告它试图连接到哪个数据库,SqlException不会告诉您。异常被转换为更一般的异常,它是该层接口的一部分,可能(或可能不会)在更高层处理。例如。DAL可能会捕获连接错误并抛出DatabaseUnavailableException。BL可能会为不重要的操作忽略它,或者可能让它为这些操作传播。如果BL捕获到SqlException,那么它将暴露给DAL的实现细节。相反,抛出DatabaseUnavailableException的可能性是DAL接口的一部分。在多层中记录同一个错误通常没有用,但我可以想到一个例外:当下层不知道问题是否严重时,它可以将其记录为警告。如果更高层确定它是关键的,它可以将相同的问题记录为错误。以下是我遵循的一些与异常处理相关的规则:SqlConnectionconn=null;尝试{conn=newSqlConnection(connString);...}//不要在这里实现任何捕获。数据库异常逻辑应该在上层实现finally{//应该始终执行的终结代码。如果(conn!=null)conn.Dispose();}首先要修复的是永远不要抛出通用异常。其次,除非有很好的理由包装异常,否则抛出;而不是在你的catch子句中抛出新的......第三(这不是一个硬性规定),不要在UI层这样做下面的任何一点都会捕获一般异常。UI层应该捕获一般异常,以便可以向最终用户显示用户友好的消息,而不是轰炸技术细节。如果您在层的更深处捕获一般异常,它可能会被无意中吞噬并导致难以追踪的错误。在任何应用程序中都很难处理异常。您需要考虑每个异常并快速进入适合您的模式。我已经尝试将异常分为以下类别之一...示例:也许您的持久性框架要求您捕获可能由格式错误的SQL引起的SQLExceptions,但是,您正在执行硬编码查询。处理:根据我的经验,大多数异常都属于这一类。至少,记录它们。更好的是,将它们发送到记录它们的异常处理服务。然后在将来如果您决定以不同的方式记录它们或对它们做不同的事情,您可以在一个地方进行更改。也许你还想向UI层发送一个标志,表明发生了某种错误,他们应该重试他们的操作。也许你给管理员发邮件。您还需要将某些东西返回到更高层,以便服务器上的生命继续。也许这是一个默认值,或者这可能是null。也许你有办法取消整个操作。另一种选择是为异常处理服务提供两种处理方法。handleUnexpectedException()方法通知用户但不会重新抛出异常,如果您有能力自行展开堆栈或以某种方式继续,则可以返回默认值。handleFatalException()方法通知用户并重新抛出某种异常,以便您可以让异常为您展开堆栈。示例:用户正在尝试更新foobar小部件并为其指定一个新名称,但是具有所需名称的foobar小部件已经存在。处理:在这种情况下,您需要将异常返回给用户。在这种情况下,您可以一直抛出异常(或者更好,甚至不捕获它)直到它到达UI层,然后UI层应该知道如何处理异常。确保记录这些异常,以便您(或编写您的UI的任何人)知道它们存在并知道期望它们。示例:您进行远程服务调用并且远程服务超时,但您知道他们有这样做的历史记录,您应该重做该调用。处理:有时这些异常从头等舱开始。在您的应用程序运行一段时间后,您会发现您确实有一种处理它的好方法。有时,与乐观锁定或中断异常一样,捕获异常并对其进行处理只是业务的一部分。在这些情况下,会处理异常。如果您的语言(我认为是Java)区分已检查异常和未检查异常,我建议使用这些异常。为了解决您的上述问题,我会将初始异常委托给一个服务,该服务将通知用户并根据MyObj的对象类型(例如设置)我可能会将其设为非致命异常并返回默认值或者如果我可以'tdo(e.g.useraccount)那么我可能会将其设为致命异常,这样我就不必担心了。我在每一层(DALException、BLException、...)中使用sepearateException类来记录(例如:在文件中)层边界处的异常(这是管理员),因为用户只会看到清晰易懂的错误消息。这些异常应该由所有数据访问层处理,因为所有层都继承自DAlBase。我们可以将异常处理集中在几个类中,开发者只会抛出layerexception(例如:DALException),参见MultiTierexceptionhandling。以上就是C#学习教程:n层应用中的异常处理?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: