如何'全局'捕获在对象实例中抛出的异常

时间:2009-03-02 03:50:05

标签: c# exception-handling global enterprise-library

我目前正在编写winforms应用程序(C#)。

我正在使用企业库异常处理块,遵循我所看到的相当标准的方法。 IE:在Program.cs的Main方法中,我将事件处理程序连接到Application.ThreadException事件等。

这种方法效果很好,可以处理应用程序异常情况。

在我的一个业务对象中,我在其中一个对象属性

的Set访问器中抛出了各种异常
set {

   if (value > MaximumTrim)
    throw new CustomExceptions.InvalidTrimValue("The value of the minimum trim...");

   if (!availableSubMasterWidthSatisfiesAllPatterns(value))
        throw new CustomExceptions.InvalidTrimValue("Another message...");

   _minimumTrim = value;
}

我对这种方法的逻辑(不将其转换为“何时抛出异常”讨论)只是业务对象负责检查业务规则约束并抛出可以冒泡并根据需要捕获的异常。应该注意的是,在我的应用程序的UI中,我明确地检查公共属性被设置为的值(并在那里显示友好的对话框等操作)但是抛出异常我也覆盖了我的业务对象的情况可能不被UI使用,例如:该属性正由另一个业务对象设置。无论如何,我想你们都明白了。

我的问题是这些异常没有被连接到Application.ThreadException的处理程序捕获,我不明白为什么。

从其他阅读中我已经完成了Application.ThreadException事件,它处理“...捕获主GUI线程上发生的任何异常”。是否在我的业务对象中引发了异常,而不是在此线程中?我没有创建任何新线程。

如果我按如下方式更新代码,我可以使用该方法,明确调用连接到Application.ThreadException的事件处理程序。这是Enterprise Library示例中概述的方法。 然而,这种方法要求我包装try catch中抛出的任何异常,这是我试图通过使用“全局”处理程序来避免的。

try
{
    if (value > MaximumTrim)
        throw new CustomExceptions.InvalidTrimValue("The value of the minimum...");

    if (!availableSubMasterWidthSatisfiesAllPatterns(value))
        throw new CustomExceptions.InvalidTrimValue("Another message");

    _minimumTrim = value;
}
catch (Exception ex)
{
    Program.ThreadExceptionHandler.ProcessUnhandledException(ex);
}

我还研究过将处理程序连接到AppDomain.UnhandledException事件,但这也没有捕获异常。

如果有人可以向我解释为什么我的异常没有被第一个代码示例中的全局异常处理程序捕获,我会很高兴。是否有其他方法我缺少或我是否坚持使用try catch包装代码,如上所示,根据需要?

3 个答案:

答案 0 :(得分:0)

作为一个想法,尝试添加(相当早期 - 即在Main的开头):

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

那就是说 - 无论有没有......对我来说似乎都很好......

答案 1 :(得分:0)

根据MSDN,只有在未处理异常时才会触发Application.ThreadException。也许在callstack的某个地方有catch处理异常?

另一种选择是尝试使用AppDomain.UnhandledException代替。它与Application.ThreadException相同,但它适用于同一AppDomain中的所有例外。

答案 2 :(得分:0)

如果您尝试使用 Application.ThreadException 要么 AppDomain.CurrentDomain.UnhandledException 调试器捕获异常!

要测试这些方法,您必须在没有调试器的情况下启动应用程序。