在使用之前尝试捕捉或反之亦然?

时间:2017-08-03 12:30:06

标签: c# try-catch database-connection using idisposable

我的做法是将try-catch block置于using block内而不是反之亦然。然而,最近,我被告知这不是正确的方法。正如他们所说,数据库连接在这种方法下没有正确关闭。

下面是我如何实现它的示例块:

using(var dbConn = new MySqlConnection(dbConnStr)) {
    using(var dbTrans = dbConn.BeginTransaction()) {
       try {
           ...
           ...
           ...

           return some_results_here;
        }
        catch(Exception Ex) {
            throw;
        }
    }
}

因此,有人告诉我,dbConndbTrans都不会自动处理(与我的信念相反,因为它们都是一次性的和使用声明)并且连接保持开放。如果确实如此,我现在感到困惑和沮丧。因为这是我在几乎所有项目中的实践,我一直没有遇到过这样的问题。

请把这个神话弄清楚。谢谢大家。

3 个答案:

答案 0 :(得分:3)

如果您在try...catch之前或之后加using,则无关紧要,因为using只是try...finally调用处置的简写。

使用与此类似:

IDisposable d = (the assignment);

try
{
}
finally
{
    if (d != null)
        d.Dispose();
}

除了一些边缘情况,在这两种情况下,您的using实例都将被处理掉。

答案 1 :(得分:1)

帕特里克的回答完全解决了这个问题,但作为额外的支持,直接来自MSDN ......

  

通常,当您使用IDisposable对象时,您应该声明和   在using语句中实例化它。 using语句调用   以正确的方式处理对象上的方法,以及(当您使用它时)   如前所示)它也会导致对象本身超出范围   只要调用Dispose。在使用块中,对象是   只读且无法修改或重新分配。

     

使用声明   确保即使在您发生异常时也会调用Dispose   正在调用对象上的方法。你可以通过实现相同的结果   将对象放在try块中,然后在a中调用Dispose   最后阻止;实际上,这就是翻译using语句的方式   由编译器。前面的代码示例扩展为以下内容   编译时的代码(注意额外的花括号来创建   对象的范围有限):

您也可以轻松找到对此的讨论:Here。总之,它会处置。

答案 2 :(得分:0)

要回答你的问题,特别是关于使用块内的throw会阻止代码运行的进一步进展的断言(因此你的使用块中的资源永远不会被处理掉)......

根据Microsoft Docs

  

“using语句确保即使在对象上调用方法时发生异常也会调用Dispose。”

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement

注意:我无法100%确定这适用于每个版本的.NET框架。如果有疑问,我建议进行测试。