【问题标题】:How do I 'globally' catch exceptions thrown in object instances如何“全局”捕获对象实例中抛出的异常
【发布时间】:2009-03-02 03:50:04
【问题描述】:

我目前正在编写一个 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 的事件处理程序,我可以让该方法正常工作。这是企业库示例中概述的方法。 但是,这种方法需要我将任何抛出的异常包装在 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 中使用包装代码,如上所示?

【问题讨论】:

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


    【解决方案1】:

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

    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
    

    也就是说——不管有没有……它对我来说似乎都很好......

    【讨论】:

    • 设置这个似乎并没有改变我的情况。属性设置器中发生的异常确实会在调试器中引发异常,但是当您继续传递它时,它不会像任何其他异常那样落入 ThreadException 事件中。
    • 值得注意的是,这个问题似乎只发生在绑定到控件的属性上。因此,如果您只是创建一个字符串属性并将其绑定到文本框,然后在属性的 setter 中抛出异常,您应该能够重现该问题。
    【解决方案2】:

    根据MSDNApplication.ThreadException 只会在未处理异常时触发。也许在处理异常的调用堆栈上某处有一个catch

    另一种选择是尝试改用AppDomain.UnhandledException。它与Application.ThreadException 相同,但它适用于同一AppDomain 中的所有异常。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 当调试器捕捉到异常时,您应该能够点击“继续”(或 VS 中的 F5)以查看异常冒泡到 ThreadException 或 UnhandledException 事件。
      猜你喜欢
      • 2012-11-21
      • 1970-01-01
      • 1970-01-01
      • 2013-11-30
      • 2019-09-18
      • 1970-01-01
      • 2021-05-08
      • 2010-10-08
      • 2013-06-24
      相关资源
      最近更新 更多