我不应该抓住哪些例外情况?

nw.*_*nw. 16 .net c# exception-handling

我有一个运行长批处理的应用程序,可能会抛出许多异常.如果在批处理中的一个项目期间抛出非关键异常,我只想记录并继续,这样我们可以稍后解决问题,同时让其他批处理项继续.

一些例外,例如OutOfMemoryException,对整个应用程序来说是毁灭性的,这些我想重新抛出,以便它们冒泡到全局异常处理程序,它将记录错误并停止应用程序.

所以我的问题是,是否有一个合理的简短列表,我可以在我的下级异常处理程序中重新抛出,同时抑制(在记录之后)其他所有内容?

谢谢!

编辑:稍微详细说明,这是我的程序的基本结构

foreach(var item in longItemList)
{
   try
   {
      bigDynamicDispatchMethod(item);
   }
   catch(Exception ex)
   {
      logException(ex);
   }
}
Run Code Online (Sandbox Code Playgroud)

可能会抛出大量异常,因为这个循环几乎是我应用程序的顶级.我项目中99%的代码都在调度方法之后.我在较低级别进行合理的异常处理,但是bug仍在继续运行,并且我不想在抛出异常后停止批处理中的其他无关进程.

试图找到可以在我的应用程序中的其他地方抛出哪些异常似乎是一项艰巨的任务,而且似乎更容易获得关键异常的黑名单.

有没有更好的方法来构建我的应用程序来处理这个?我愿意接受建议.

Dmi*_*try 26

您不需要"坏"异常列表,默认情况下应将所有内容视为坏内容.只抓住你可以处理和恢复的东西.CLR 可以 通知您未处理的异常,以便您可以适当地记录它们.除了黑名单的异常之外,吞下一切都不是修复bug的正确方法.这只会掩盖他们.阅读本文此内容.

为了转移异常而捕获时不要排除任何特殊异常.

您应该只捕获可以合法处理的异常,而不是在catch子句中创建特殊异常列表.在非特定异常处理程序中,不应将您无法处理的异常视为特殊情况.以下代码示例演示了为重新抛出特殊异常而错误地测试特殊异常.

public class BadExceptionHandlingExample2 {
    public void DoWork() {
        // Do some work that might throw exceptions.
    }
    public void MethodWithBadHandler() {
        try {
            DoWork();
        } catch (Exception e) {
            if (e is StackOverflowException ||
                e is OutOfMemoryException)
                throw;
            // Handle the exception and
            // continue executing.
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

其他规则很少:

通过在应用程序代码中捕获非特定异常(例如System.Exception,System.SystemException等)来避免处理错误.有些情况下,处理应用程序中的错误是可以接受的,但这种情况很少见.

应用程序不应处理可能导致意外或可利用状态的异常.如果您无法预测异常的所有可能原因并确保恶意代码无法利用生成的应用程序状态,则应允许应用程序终止而不是处理异常.

当您理解为什么它会在给定的上下文中抛出时,请考虑捕获特定的异常.

您应该只捕获可以从中恢复的异常.例如,尝试打开不存在的文件导致的FileNotFoundException可以由应用程序处理,因为它可以将问题传达给用户并允许用户指定不同的文件名或创建文件.不应处理打开生成ExecutionEngineException的文件的请求,因为无法以任何确定性知道异常的根本原因,并且应用程序无法确保继续执行是安全的.

Eric Lippert将所有异常分为4组:致命,'斩首',Vexing,外生.以下是我对Eric的建议的解释:

  Exc. type | What to do                          | Example
------------|-------------------------------------|-------------------
Fatal       | nothing, let CLR handle it          | OutOfMemoryException
------------|-------------------------------------|-------------------
Boneheaded  | fix the bug that caused exception   | ArgumentNullException
------------|-------------------------------------|-------------------
Vexing      | fix the bug that caused exception   | FormatException from 
            | (by catching exception  because     | Guid constructor
            | the framework provides no other way | (fixed in .NET 4.0 
            | way of handling). Open MS Connect   | by Guid.TryParse)
            | issue.                              | 
------------|-------------------------------------|-------------------
Exogenous   | handle exception programmatically   | FileNotFoundException 
Run Code Online (Sandbox Code Playgroud)

这大致相当于Microsoft的分类:用法,程序错误和系统故障.您还可以使用FxCop等静态分析工具来强制执行其中一些规则.

  • 您也可以处理烦恼的例外情况.它们是无理取闹的,因为你必须*在大多数情况下处理它们. (4认同)
  • 看起来很棒!___ (2认同)

Ode*_*ded 11

不要抓住任何你不知道如何安全处理的例外情况.

捕获Exception是一种特别糟糕的做法,唯一更糟的是catch没有指定任何托管异常类型(因为它也会捕获非托管异常).