简体   繁体   English

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

[英]How do I 'globally' catch exceptions thrown in object instances

I am currently writing a winforms application (C#). 我目前正在编写一个winforms应用程序(C#)。

I am making use of the Enterprise Library Exception Handling Block, following a fairly standard approach from what I can see. 我正在使用企业库异常处理块,遵循我所看到的相当标准的方法。 IE : In the Main method of Program.cs I have wired up event handler to Application.ThreadException event etc. IE:在Program.cs的Main方法中,我将事件处理程序连接到Application.ThreadException事件等。

This approach works well and handles the applications exceptional circumstances. 这种方法运行良好,可以处理应用程序异常情况。

In one of my business objects I throw various exceptions in the Set accessor of one of the objects properties 在我的一个业务对象中,我在其中一个对象属性的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;
}

My logic for this approach (without turning this into a 'when to throw exceptions' discussion) is simply that the business objects are responsible for checking business rule constraints and throwing an exception that can bubble up and be caught as required. 我对这种方法的逻辑(不将其转换为“何时抛出异常”讨论)只是业务对象负责检查业务规则约束并抛出可以冒泡并根据需要捕获的异常。 It should be noted that in the UI of my application I do explictly check the values that the public property is being set to (and take action there displaying friendly dialog etc) but with throwing the exception I am also covering the situation where my business object may not be used by a UI eg : the Property is being set by another business object for example. 应该注意的是,在我的应用程序的UI中,我明确地检查公共属性被设置为的值(并在那里显示友好的对话框等操作)但是抛出异常我也覆盖了我的业务对象的情况可能不被UI使用,例如:该属性正由另一个业务对象设置。 Anyway I think you all get the idea. 无论如何,我认为你们都明白了。

My issue is that these exceptions are not being caught by the handler wired up to Application.ThreadException and I don't understand why. 我的问题是这些异常没有被连接到Application.ThreadException的处理程序捕获,我不明白为什么。

From other reading I have done the Application.ThreadException event and it handler "... catches any exception that occurs on the main GUI thread". 从其他阅读中我已经完成了Application.ThreadException事件,它处理“...捕获主GUI线程上发生的任何异常”。 Are the exceptions being raised in my business object not in this thread? 是否在我的业务对象中引发了异常,而不是在此线程中? I have not created any new threads. 我还没有创建任何新线程。

I can get the approach to work if I update the code as follows, explicity calling the event handler that is wired to Application.ThreadException. 如果我按如下方式更新代码,我可以使用该方法,明确调用连接到Application.ThreadException的事件处理程序。 This is the approach outlined in Enterprise Library samples. 这是Enterprise Library示例中概述的方法。 However this approach requires me to wrap any exceptions thrown in a try catch, something I was trying to avoid by using a 'global' handler to start with. 然而,这种方法要求我包装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);
}

I have also investigated using wiring a handler up to AppDomain.UnhandledException event but this does not catch the exceptions either. 我还研究过将处理程序连接到AppDomain.UnhandledException事件,但是这也没有捕获异常。

I would be good if someone could explain to me why my exceptions are not being caught by my global exception handler in the first code sample. 如果有人可以向我解释为什么我的异常没有被第一个代码示例中的全局异常处理程序捕获,我会很高兴。 Is there another approach I am missing or am I stuck with wrapping code in try catch, shown above, as required? 是否有其他方法我缺少或我是否坚持使用try catch包装代码,如上所示,根据需要?

If you try to use use Application.ThreadException or AppDomain.CurrentDomain.UnhandledException the Debugger will catch the exception! 如果您尝试使用Application.ThreadException或AppDomain.CurrentDomain.UnhandledException, 调试器捕获异常!

To test these methods you have to start the appication without a debugger. 要测试这些方法,您必须在没有调试器的情况下启动应用程序。

As a thought, try adding (fairly early on - ie at the start of Main ): 作为一个想法,尝试添加(相当早 - 即在Main的开头):

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

That said - it seems to work fine for me with or without... 那就是说 - 无论有没有,它似乎都适合我...

According to MSDN , Application.ThreadException will only be fired if the exception isn't handled. 根据MSDN ,只有在未处理异常时才会触发Application.ThreadException Maybe there is a catch somewhere up the callstack that is handling the exception? 也许在处理异常的callstack的某个地方有一个catch

Another option would be to try using AppDomain.UnhandledException instead. 另一种选择是尝试使用AppDomain.UnhandledException It is the same as Application.ThreadException , except it works for all exceptions in the same AppDomain . 它与Application.ThreadException相同,但它适用于同一AppDomain中的所有异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM