何时使用,何时不使用 Try Catch Final
Posted
技术标签:
【中文标题】何时使用,何时不使用 Try Catch Final【英文标题】:When to use and when not to use Try Catch Finally 【发布时间】:2011-03-12 07:23:39 【问题描述】:我在 .net 3.5 中创建 asp.net web 应用程序,我想知道何时使用以及何时不使用 Try Catch finally 块?特别是,我的大部分尝试捕获都围绕执行存储的过程和填充文本字段或网格视图?当您执行存储过程并填充数据显示控件时,您会使用 Try Catch EVERYTIME 吗?
我的代码块通常如下所示:
protected void AddNewRecord()
try
//execute stored proc
// populate grid view controls or textboxes
catch (Exception ex)
//display a messagebox to user that an error has occured
//return
finally
【问题讨论】:
另见:***.com/questions/505471/… 查看 J. Richter 所著的“CLR via C#”第 3 版一书。它非常详细地介绍了异常处理的概念,绝对是一本很好的参考书。 【参考方案1】:答案是“视情况而定”。
您可能希望在每个原子操作周围使用try... catch ...
,以便在出现问题时可以回滚到上一个良好状态(使用事务)。这可能是一个或多个存储过程 - 这取决于您的应用程序。
如果您要捕获异常,请确保您明确捕获了哪些异常。您不应该使用 catch (Exception ex)
或 catch()
(称为“捕获所有”异常处理),而是使用特定的 catch 语句,例如 catch (IndexOutOfRangeException ex)
(例如)。
但是,如果您无法处理异常或者您无法进行清理,那么您不应该捕获它。
【讨论】:
“原子”操作是什么意思? @user279521 - “原子” - 就像一个原子,它不能被进一步分割。它可能有许多步骤,但如果单独执行每个步骤,则没有任何意义。例如,如果您修复了代码中的错误,但需要对多个类进行编辑,则所有文件的签入被认为是原子的,因为仅签入一个文件没有任何意义。 @Chris S - 如果你要学究气的话 ;) 它来自希腊语,ἄτομος (átomos),意思是不可切割/不可分割的。【参考方案2】:在发生特定异常时应继续执行的最内层循环中使用“try catch”。请注意,如果您有一个执行 10,000 次的循环并且发生异常,例如第十次重复不会影响其他 9,990,它可能有助于捕获异常并让循环继续进行。另一方面,如果异常指示的错误表明循环的第 11、12、13 次等也将失败,那么让异常终止循环比继续重试操作要快得多那是行不通的。
【讨论】:
【参考方案3】:您期望存储过程中的Exception
是什么?如果您不使用pokemon exception handling 并且确切地知道您的应用程序应该做什么,那么任何不符合您想要捕获的特定异常的东西都将被Application
对象捕获。
换句话说,不要使用catch
或catch (Exception)
,而是专门的异常处理:
catch(SqlException e)
// Log stacktrace and show a friendly error to your user
Application.Error 事件是应该捕获意外行为的地方,并且比简单地让客户回复您说“我的字段没有显示任何内容”更容易追踪。
【讨论】:
没有特别的例外,但是“为了安全起见”,过去我被告知所有数据库调用都应该包装在 try catch 块中。 但是你不需要捕获异常。您可以愉快地捕获所有 SqlExceptions 或您正在使用的任何数据库。如果抛出了其他东西,您可能会想知道它而不是默默地死去【参考方案4】:除了别人说的,一定要避免这样做:
try
throw new ApplicationException("Fake sql ex");
//catch and do nothing. swallowing exceptions
catch(Exception)
【讨论】:
Pokemon 异常处理:必须抓住它们!【参考方案5】:正如其他人所说,这取决于。我倾向于在两种情况下使用 try/catch/finally 块:
我需要以某种方式处理异常,而不是简单地重新抛出它。
我需要清理finally
块中的一些资源。
除了这两种情况,我让调用代码处理任何可能发生的异常。
【讨论】:
顺便说一句,using
基本上是一个用于清理资源的try-finally
块(通过Dispose
)。
@Brian - 正确,但并非所有需要清理的东西总是实现 IDisposable(或 Dispose)。【参考方案6】:
当您打算在 catch 块中处理异常时,您应该只使用try catch
。我所说的句柄是,记录错误,因为错误选择不同的路径等。如果你只是打算重新抛出它,那么尝试捕获是没有意义的。
【讨论】:
如果您想记录错误,则无需在异常发生时捕获异常——相反,您可以在代码的退出点捕获任何异常出现在代码中的任何位置。 您说得很好,但我认为这在很大程度上取决于应用程序的整体架构。真的,我只是提供它作为何时可能使用 try catch 的示例。 如果一个对象的不变量依赖于一个块中的所有代码执行怎么办?我认为在这种情况下,代码应该由一个块保护,如果在对象的不变量可能不成立的时候发生异常,该块将明确使对象无效。如果异常会导致调用代码放弃损坏对象,放弃损坏对象的行为将解决问题。如果调用代码尝试使用损坏的对象,这种尝试应该会导致异常,从而迫使进一步展开,直到事情得到解决或它们完全死亡。【参考方案7】:大多数时候你不应该捕捉异常。在某些地方确实可以捕获异常,例如,
何时可以从该特定异常中恢复。 当您需要记录或报告它时(例如,向用户报告)——通常在代码的顶层。 当你的代码的调用者不能处理异常时,你需要将它们转换成其他的错误格式。
此外,using 块语句可用于在 IDisposable 对象上实际调用 Dispose,从而无需 try...finally。
【讨论】:
如果我想向用户显示一个消息框“加载数据时发生错误”怎么办?如果没有 Try Catch 块,我将如何做到这一点? 需要try-catch才能弹出异常消息框 正如我所说,您只需要在代码的顶层:“当您需要记录或报告它(例如,向用户)时——通常在顶层你的代码。”以上是关于何时使用,何时不使用 Try Catch Final的主要内容,如果未能解决你的问题,请参考以下文章