C# try/catch vs AppDomain.UnhandledException记录应用程序并使其崩溃

C# try/catch vs AppDomain.UnhandledException记录应用程序并使其崩溃,c#,.net,exception-handling,try-catch,C#,.net,Exception Handling,Try Catch,据我所知,只有在实际处理异常时才应该使用try/catch,而不仅仅是报告和记录异常,然后使应用程序崩溃。否则,您最好只检查有意义的不同场景,例如,如果sth==null,或者-如果您的目的只是记录异常并使应用程序崩溃-使用。但情况总是这样吗?为什么 假设下面的方法接受一个数组,并在执行一些数据库和文件系统操作后返回MemoryStream MemoryStream Read (int[] IDs) { try { using (SqlConnection con

据我所知,只有在实际处理异常时才应该使用try/catch,而不仅仅是报告和记录异常,然后使应用程序崩溃。否则,您最好只检查有意义的不同场景,例如,如果sth==null,或者-如果您的目的只是记录异常并使应用程序崩溃-使用。但情况总是这样吗?为什么

假设下面的方法接受一个数组,并在执行一些数据库和文件系统操作后返回MemoryStream

MemoryStream Read (int[] IDs)
{
    try
    {
        using (SqlConnection connection = new SqlConnection(connection_string))
        {
            connection.Open();    

                        // a bunch of code executing SQL queries & constructing MemoryStream, which is returned at the end of the block
        }
    }
    catch (Exception e)
    {
        // report the exception to the user & log it
        throw; // pointles??                
    }
}
有多种情况可被视为异常/不想要的行为,例如:

参数ID[]为空, 无法建立SQL连接, 无法执行特定的SQL查询。
所有这些情况都被认为是异常的,仍然将所有内容都放在try/catch中如果您只想记录异常,那么崩溃可能是一种不好的做法——但为什么呢?在上述情况下,最好的处理行为是什么?完全避免try/catch,在这种情况下使用if语句返回null检查null引用,并使用AppDomain.UnhandledException记录所有其他内容?使用try/catch,但仍然使用if语句检查内部的空引用,并在这种情况下返回?还有别的吗?

在代码中添加try/catch语句只会使应用程序崩溃,这是没有效果的。CLR已经为您处理好了。还有AppDomain.UnhandledException,可以生成适当的信息来诊断原因


<>只有在非常具体的情况下,你必须清理一些东西,比如说你不想继续写的文件,你是否应该考虑写一个尝试/捕获。这本身是一个非常不确定的要求,不能保证catch块会执行。当异常严重时,如StackOverflowException或ExecutionEngineeException,则不会出现异常。或者更常见的原因是程序在运行后不进行清理,有人被电源线绊倒或任务管理器中的进程被终止。

在代码中添加try/catch语句只会使应用程序崩溃,这是没有效果的。CLR已经为您处理好了。还有AppDomain.UnhandledException,可以生成适当的信息来诊断原因

<>只有在非常具体的情况下,你必须清理一些东西,比如说你不想继续写的文件,你是否应该考虑写一个尝试/捕获。这本身是一个非常不确定的要求,不能保证catch块会执行。当异常严重时,如StackOverflowException或ExecutionEngineeException,则不会出现异常。或者更常见的原因是程序在运行后不进行清理,有人被电源线绊倒,或者任务管理器中断了进程

您应该只在实际处理异常时使用try/catch,而不只是报告和记录异常,然后使应用程序崩溃

我同意第一部分,尽管我要补充的是,当您可能无法控制调用层时,在层边界添加日志记录是有价值的。e、 g.我在顶部方法中记录Web服务中发生的所有异常,以确保我在服务器上进行了日志记录,因为调试信息堆栈跟踪等并不总是正常地跨通信层

在您的特定示例中,我将检查异常情况,您可以让其他异常自然发生。对于您的具体示例:

参数ID[]为空, 无法建立SQL连接, 无法执行特定的SQL查询。 对于第一种情况,我检查空参数有一个原因:NullReferenceException不提供有关异常原因的上下文,除了它发生的位置。我更喜欢检查null,然后抛出一个新的ArgumentNullException异常,因为您可以添加哪个参数为null。您可能仍然需要进行一些挖掘,以找出它为null的原因,但这样可以节省大量调试时间

SQL异常通常会自然而然地冒出来,因为它们包含相当多的错误信息,例如未声明的变量'@arg'

您应该只在实际处理异常时使用try/catch,而不只是报告和记录异常,然后使应用程序崩溃

我同意第一部分,尽管我要补充的是,当您可能无法控制调用层时,在层边界添加日志记录是有价值的。e、 g.我在顶部方法中记录Web服务中发生的所有异常,以确保我在服务器上进行了日志记录,因为调试信息堆栈跟踪等并不总是正常地跨通信层

在您的特定示例中,我将检查异常情况,您可以让其他异常自然发生。对于您的具体示例:

参数ID[]为空, 无法建立SQL连接, 无法执行特定的SQL查询 Y 对于第一种情况,我检查空参数有一个原因:NullReferenceException不提供有关异常原因的上下文,除了它发生的位置。我更喜欢检查null,然后抛出一个新的ArgumentNullException异常,因为您可以添加哪个参数为null。您可能仍然需要进行一些挖掘,以找出它为null的原因,但这样可以节省大量调试时间


SQL异常通常会自然而然地冒出来,因为它们包含相当多的错误信息,例如未声明的变量“@arg”

我最近也开始阅读这个主题。我的基本理解是:

仅当您计划处理异常时才捕获它。 过度使用try/catch可能导致异常吞噬和/或丢失有价值的堆栈跟踪信息,并可能导致可维护性问题。如果您决定标准化错误/日志记录,该怎么办?。而是使用try/finally或使用块来实现清理。 通过全局异常处理程序捕获边界处的异常。 使用AppDomain.UnhandledException完全符合名称的含义:记录未处理的异常。如果不记录这些日志,则在日志查看器中只会找到一个CLR Windows错误报告条目和一些对您没有任何用处的转储文件。利用AppDomain.UnhandledException始终是一个好主意,这样,如果您的应用程序确实崩溃,您就知道原因了。 需要注意的是,处理异常并不一定意味着清理或追溯逻辑。处理可能仅仅意味着将错误格式化为更用户友好的格式,或者隐藏您不希望任何人看到的敏感堆栈跟踪。我经常记录一个详细的错误并返回一个格式化的错误

同样,这正是我最初收集的。以下是一些资料来源:


我最近也开始阅读这个话题。我的基本理解是:

仅当您计划处理异常时才捕获它。 过度使用try/catch可能导致异常吞噬和/或丢失有价值的堆栈跟踪信息,并可能导致可维护性问题。如果您决定标准化错误/日志记录,该怎么办?。而是使用try/finally或使用块来实现清理。 通过全局异常处理程序捕获边界处的异常。 使用AppDomain.UnhandledException完全符合名称的含义:记录未处理的异常。如果不记录这些日志,则在日志查看器中只会找到一个CLR Windows错误报告条目和一些对您没有任何用处的转储文件。利用AppDomain.UnhandledException始终是一个好主意,这样,如果您的应用程序确实崩溃,您就知道原因了。 需要注意的是,处理异常并不一定意味着清理或追溯逻辑。处理可能仅仅意味着将错误格式化为更用户友好的格式,或者隐藏您不希望任何人看到的敏感堆栈跟踪。我经常记录一个详细的错误并返回一个格式化的错误

同样,这正是我最初收集的。以下是一些资料来源:


有很多原因可以捕捉到一个你不打算在之后清理的异常。一种是格式化异常并返回用户友好的内容,或者防止敏感堆栈跟踪信息被广播到世界各地。另外,在catch块示例中,您不会使用catch进行文件清理,而是使用finally块;它总是保证在异常发生后执行。确切地说,据我所知,最终{}实际上并不保证总是执行-例如,StackOverflowException或电源故障不会导致其执行。在标准异常的情况下,您将需要记录/处理它,它保证执行。我认为考虑堆栈溢出或电源故障可能有点过分了。有很多原因可以捕捉到一个你不打算在之后清理的异常。一种是格式化异常并返回用户友好的内容,或者防止敏感堆栈跟踪信息被广播到世界各地。另外,在catch块示例中,您不会使用catch进行文件清理,而是使用finally块;它总是保证在异常发生后执行。确切地说,据我所知,最终{}实际上并不保证总是执行-例如,StackOverflowException或电源故障不会导致其执行。在标准异常的情况下,您将需要记录/处理它,它保证执行。我认为考虑堆栈溢出或电源故障可能有点过分。即使你觉得我的答案没有用,我建议你阅读我提供的链接。我相信你会发现它们是无价之宝@艾伦,谢谢你的回答,我确实觉得它很有用,我正在阅读链接=即使你不觉得我的答案有用,我建议你阅读我提供的链接。我相信你会发现它们是无效的
不可能@艾伦,谢谢你的回答,我确实觉得它很有用,我正在阅读链接=很好的链接,谢谢。如果您只是想以一致的方式报告和记录异常,那么实现全局异常处理程序似乎是一个不错的选择——这里提供了一个干净的示例实现:非常好的链接,谢谢。如果您只是想以一致的方式报告和记录异常,那么实现全局异常处理程序似乎是一个不错的选择—这里提供了一个干净的示例实现: