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

C# 在线程中处理catch块中抛出的异常的最佳实践。(.NET),c#,.net,multithreading,exception-handling,C#,.net,Multithreading,Exception Handling,在处理线程执行中的异常时,您的看法是什么?更具体地说,如果在try-catch子句的catch块内抛出异常,该怎么办?如果异常未处理,线程会发生什么情况?您对在线程执行过程中处理异常有何看法 您应该尽可能地处理异常,也应该在您期望异常时处理异常。 澄清:我完全同意John的观点,你不应该在任何地方都处理异常——只有在你可以做些事情的地方。但是,您决不能让线程中的异常未经处理,因为这将导致严重的问题。拥有一个根异常处理程序,让你的线程优雅地消亡(在记录问题等之后) 更具体地说,如果线程被抛出到tr

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

您对在线程执行过程中处理异常有何看法

您应该尽可能地处理异常,也应该在您期望异常时处理异常。 澄清:我完全同意John的观点,你不应该在任何地方都处理异常——只有在你可以做些事情的地方。但是,您决不能让线程中的异常未经处理,因为这将导致严重的问题。拥有一个根异常处理程序,让你的线程优雅地消亡(在记录问题等之后)

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

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

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

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

正如本所提到的:


线程中未捕获的异常 在中触发未处理的异常 线程的AppDomain。你可以看 通过添加事件处理程序,可以实现以下目标:

AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

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

AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

AppDomain.CurrentDomain.UnhandledException+=CurrentDomain\u UnhandledException

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

只有在实际能够处理异常的情况下才能处理异常。只有当你能对出错的地方做些什么,或者添加信息时。不要仅仅因为你可以处理它们

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

上述情况非常糟糕。首先,不显示整个异常,只显示消息。第二,你让事情继续,你不知道进程处于什么状态。

线程中未处理的异常会导致进程死亡,并在事件日志中显示一条没有帮助的消息


在每个记录(可能重新抛出)的线程中都有顶级异常处理程序是一种很好的做法,正如其他响应提到的安装appdomain异常处理程序一样。

如果您认为可以处理异常,您应该捕获它。所有其他无法处理的异常都应该冒泡到堆栈的表面,如果在此过程中没有找到合适的处理程序,就会让线程消亡。


您不应该在catch块中编写任何可能引发另一个异常的代码,但如果需要,您可以在其周围嵌套另一个try-catch块。

从根本上说,.net异常机制不能提供任何好的方法来处理catch块执行期间或“finally”执行期间发生的异常在另一个异常挂起时阻止。正确的处理要求.net支持复合异常类型,该类型可以被其任何组成部分的“catch”块捕获,但会自动重新启动调用堆栈,直到处理完所有组成部分。不幸的是,.net没有提供任何这样的复合异常类型;虽然可以通过这样的方式定义和使用自定义类型以获得这样的语义,但是使用它们的代码将非常难看,并且它们不会与其他代码可能抛出的异常很好地集成


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

@rein:不仅线程死亡;我建议你把Ben答案中的信息整合到你最后的陈述中。如果存在未处理的异常,线程确实会死亡,但不会停止。如果没有其他处理程序,异常将向上传播到AppDomain链,并杀死你的应用。同意。我不想暗示在每一段代码周围都应该有try-catch块。谢谢你的关注,我完全同意。rein回答的语气(尽管他澄清他并非有意暗示这一点)可能对初学者来说,编写try-catch块是一件好事。我会说,尝试编写代码异常安全,尽可能少的try-catch块;只有这样,你才能开始关注那些你可以在非常特殊的情况下处理的异常。只有在应用程序的顶层(可能是应用程序层的主要边界),才需要关注捕获所有异常(用于报告&优雅地让应用程序死掉),但请注意,您不能以传统的方式“处理”异常。执行此事件处理程序后,AppDomain可能会死掉。使用此事件主要是为了记录有关异常或类似操作的信息。是的,我应该提到这一点。