End Using会关闭已打开的SQL连接吗?

66

如果我将SQLConnection包装在Using语句中,我需要关闭它吗?还是使用结束会处理它?

using cn as new system.data.sqlclient.sqlconnection()
    cn.open
    '{do a bunch of other stuff with commands and datareaders here}
    cn.close 'Do I need this?
end using 
6个回答

96

退出 using 代码块会调用相关对象(例如您的示例中的cn)的 .Dispose() 方法,对于 SqlConnection 对象来说,这将关闭连接和任何打开的资源。


3
如果在 using 块内部抛出异常会发生什么?连接是否仍然会被处理? - Youssef
10
乔尔·科霍恩的"Yes."这个回答含义不明确。完整的回答是:"你不需要关闭,因为结束会处理它"。 - Michael Freidgeim
1
据我所知,它确实会调用.Dispose()方法,但只有在连接池未激活时才会关闭。使用连接池时,连接通常会返回到池中,或者在满足某些“清理”条件时关闭,因此一般情况下无法确定是否已关闭.. 实际上从您的角度来看,它是“关闭”的,因为它变得可供池中的下一个需要连接的对象使用。 - Luke

31

更准确地说,调用Dispose或Close方法会将底层物理连接标记为“未使用”,但并不会真正关闭它。一个“未使用”的连接如果尚未被物理关闭,则可以用于连接池。因此,调用Dispose会将连接返回到连接池。


1
抱歉..你说调用Dispose或Close“并没有真正关闭它”,然后你又说“调用Dispose会将连接返回到池中”。你能澄清一下吗? a) Dispose既关闭它,又将其返回到池中吗? b) Close在关闭之后也会将其返回到池中吗?还是只有在Dispose之后才会返回到池中? - ingredient_15939
2
为什么会检查错误的答案?显然已知close/dispose并不会真正关闭连接,而是将其带回池中。 - Royi Namir

13

4

虽然 SQL 的 Dispose 方法确实会关闭连接(根据 darin 的说法,最终会关闭),但你应该保留 Close 方法的调用。原因在于,你不能依赖于 Dispose 的底层实现来调用 close 方法。而且对于那些编写过非托管语言的人来说,看到 Open 没有 Close 就像看到 New 没有 Delete 一样。这是我觉得代码有问题的地方。


我同意代码有异味。我喜欢显式编程,而不是隐式编程。 - Astra
24
我不同意。这只是噪音。学习使用区块的新范式。 - TrueWill
我讨厌“代码异味”这个说法,不知道为什么人们认为可以使用它。在我看来,你是过于龟毛了,using语句的结束括号表达了该语句所使用资源的处理方式。你可以争辩说显式的Close调用会在代码文件中增加3行,可能导致using语句块变得足够大,以至于在代码编辑器中无法再看到using块的第一行,这可能比显式的Close语句更不方便开发人员的敏感性,因为有一个Open语句。 - Brian Ogden

2

"Using块的行为类似于Try...Finally结构,其中Try块使用资源,而Finally块处理其释放。因此,无论如何退出块,Using块都保证释放资源。即使是未处理的异常,这也是正确的,但StackOverflowException除外。"
https://msdn.microsoft.com/en-us/library/htd05whh.aspx


2

使用using只是try/finally的一种简写方式。以下代码与您发布的代码等效:

Try
    SqlConnection cn as new system.data.sqlclient.sqlconnection()
    cn.open
    '{do a bunch of other stuff with commands and datareaders here}
    cn.close 'Do I need this?
Finally
    cn.Dispose()
End Try

Dispose方法旨在处理所有资源清理工作,对于连接来说,它将关闭连接。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接