在线程中处理在 catch 块中抛出的异常的最佳实践。 (。网)

Posted

技术标签:

【中文标题】在线程中处理在 catch 块中抛出的异常的最佳实践。 (。网)【英文标题】:Best practice to handle exception, that is thrown within catch block, in a thread. (.NET) 【发布时间】:2010-11-12 18:12:08 【问题描述】:

您对处理线程执行中的异常有何看法?更具体地说,如果在 try-catch 子句的 catch 块中抛出异常怎么办?如果异常未处理,线程会发生什么?

【问题讨论】:

【参考方案1】:

我不得不不同意 ren,或者至少不同意他的意思。

只有在您确实处理异常时才处理它们。仅当您可以对出现的问题采取措施或添加信息时。不要仅仅因为你可以就处理它们。

try 
    // ..
 catch (Exception ex) 
    Console.WriteLine(ex.Message);

上面的内容很糟糕。首先,您不显示整个异常,而只显示消息。其次,你让事情继续下去,你不知道进程处于什么状态。

【讨论】:

同意。我不想暗示每一位代码都应该有 try-catch 块。感谢您了解这一点。 我完全同意。 rein 的回答语气(尽管他澄清说他并不是要暗示这一点)对于初学者来说,编写 try-catch 块是一件好事。我想说,尝试编写异常安全的代码,尽可能少地使用 try-catch 块;然后才开始关心您可以在非常特定的情况下实际处理的异常。仅在应用程序的顶层(也可能是应用程序层的主要边界),关注捕获所有异常(用于报告和优雅地让您的应用程序死亡)【参考方案2】:

您对处理线程执行中的异常有何看法?

您应该尽可能地处理异常,并在您期望异常时处理。 澄清:我完全同意约翰的观点,你不应该在任何地方处理异常——只有在你可以对它们做些什么的地方。但是,您永远不应该让线程中的异常未经处理,因为这会导致严重的问题。有一个根异常处理程序,让你的线程优雅地死掉(在记录问题等之后......)

更具体地说,如果线程被抛出在 try-catch 子句的 catch 块中怎么办?

您的意思是:如果在 catch 块中抛出异常怎么办?好吧,然后它会被当前的 try-catch 块处理。最好不要将过多的处理放在catch块中,尽可能避免这种情况。

如果线程未处理,线程会发生什么?

您的意思是:如果异常未处理,线程会发生什么?它死了。

正如本所说:

线程中未捕获的异常 在 线程的 AppDomain。你可以关注 这些通过添加事件处理程序:

AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

【讨论】:

@rein:不仅线程死了;它取消了整个过程。 我建议以某种方式将本回答中的信息纳入您的最后陈述。如果有未处理的异常,线程确实会死掉,但它不会停在那里。如果您没有其他处理程序,该异常将向上传播到 AppDomain 并终止您的应用程序。【参考方案3】:

线程中未捕获的异常会在线程的 AppDomain 中触发 UnhandledException。您可以通过添加事件处理程序来观察这些:

AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

【讨论】:

请注意,尽管您可以“处理”传统意义上的异常。执行此事件处理程序后,AppDomain 很可能会死掉。使用此事件主要是为了能够记录有关异常或类似操作的信息。 是的——我应该提到这一点。【参考方案4】:

线程中未处理的异常会导致您的进程终止,并在事件日志中显示无用的消息。

在每个记录日志(并且可能重新抛出)的线程中拥有***异常处理程序是一种很好的做法,正如其他回复提到的那样安装 appdomain 异常处理程序。

【讨论】:

【参考方案5】:

如果你认为你可以处理异常,你应该捕获它。所有其他无法处理的异常都应该冒泡到堆栈的表面,如果一路上没有找到合适的处理程序,就会让线程死亡。 您不应该在可能引发另一个异常的 catch 块中编写任何代码,但如果需要,您可以在其周围嵌套另一个 try catch 块。

【讨论】:

【参考方案6】:

.net 异常机制基本上没有提供任何好的方法来处理在 catch 块执行期间发生的异常,或者在另一个异常未决时执行“finally”块期间发生的异常。正确处理需要.net 支持一种复合异常类型,该类型可以被其任何组成部分的“catch”块捕获,但会自动重新抛出调用堆栈,直到处理完所有组成部分。不幸的是,.net 没有提供任何这样的复合异常类型。虽然可以定义和使用自定义类型以获得这样的语义,但使用它们的代码会相当丑陋,并且它们不能很好地与其他代码可能抛出的异常集成。

因此,人们面临一个选择:扼杀新异常并让旧异常传播,让新异常传播并丢失旧异常,或者制作一个只能由知道的代码处理的复合异常对象寻找它。这些都不是特别令人愉快的选择。哪一个最好取决于对不同异常类型所代表的条件的理解,以及调用代码将如何处理它们。

【讨论】:

以上是关于在线程中处理在 catch 块中抛出的异常的最佳实践。 (。网)的主要内容,如果未能解决你的问题,请参考以下文章

一个问题:关于finally中return吞掉catch块中抛出的异常

在 PHP Try Catch 块中抛出异常

在PHP Try Catch块中抛出异常

finally中流关闭失败需要抛出异常吗

JAVA语言如何进行异常处理,关键字throws,throw,try,catch,finally分别代表啥意义在try块中抛出异常吗

如果在 catch 块中抛出异常,是不是会执行 finally 块? [复制]