我的做法是将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;
}
}
}
因此,有人告诉我,dbConn
和dbTrans
都不会自动处理(与我的信念相反,因为它们都是一次性的和使用声明)并且连接保持开放。如果确实如此,我现在感到困惑和沮丧。因为这是我在几乎所有项目中的实践,我一直没有遇到过这样的问题。
请把这个神话弄清楚。谢谢大家。
答案 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会阻止代码运行的进一步进展的断言(因此你的使用块中的资源永远不会被处理掉)......
“using语句确保即使在对象上调用方法时发生异常也会调用Dispose。”
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement
注意:我无法100%确定这适用于每个版本的.NET框架。如果有疑问,我建议进行测试。