设置 Adodb.recordset 对象为 nothing 之前需要关闭它吗?

12
Dim rs as ADODB.Recordset
set rs = ReturnARecordset 'assume ReturnARecordset does just that...

'do something with rs

rs.Close
set rs = Nothing

在将rs设置为“nothing”之前,有必要调用rs.Close吗?

编辑:我们有一个全局连接,整个应用程序都会使用这个连接,所有的记录集对象都使用这个连接。下面有两个答案谈到需要关闭记录集以确保连接不会一直处于打开状态。对我来说,这听起来像是很愚蠢的话,因为连接是由连接对象控制的,而不是记录集对象,对吗?但如果我遗漏了些什么,请告诉我...

4个回答

7
唯一需要显式调用Close的原因是当您不确定记录集是否被项目中的其他地方引用时,通常是由于一些松散的编码导致的。
Dim rs as ADODB.Recordset
Set rs = ReturnARecordset
...
MyControl.ObscureMethod rs
...
Set rs = Nothing

最后一行应该在不显式调用Close的情况下终止记录集实例,除非MyControl持有额外的引用并因此防止正常拆除。 在rs上调用Close将确保MyControl无法将其引用用于任何有用的事情,同时也将导致崩溃。


我的想法完全一样。我主要在尝试弄清楚是否有有效的理由调用对于函数内部私有且很快超出范围的记录集变量的Close方法。 - Brandon Moore
4
调用Close,显式将本地引用设置为Nothing是互联网代码库充斥着的同一种“ Cargo Cult programming ”。最好的方法是使用常识,在您特定的环境中测试是否存在内存泄漏。 - wqw
是的,当我知道它即将超出范围时,我从不将其设置为“nothing”。但我不想听到关于将其设置为“nothing”重要性的多个答案,因为那不是我的问题,所以我加了这行代码来防止这些评论 :) - Brandon Moore

4

是的,这不仅仅强制进行垃圾收集,还告诉服务器连接正在被终止,这避免了多个打开的孤立连接(它们最终会自行超时),但最好的做法是将它们关闭。

当ADODB使用远程连接而不是本地连接时,尤其明显。


1
这没有意义。Recordset.Open需要一个连接对象作为参数,关闭记录集不会关闭连接。我们的应用程序有一个单独的连接对象,在整个应用程序的生命周期中保持打开状态,所有查询都使用此对象。因此,在这种情况下,是否有其他关闭记录集的原因?我认为当记录集的引用计数达到0时,它将在其析构函数中处理任何调用Close的内容,但我不确定,所以我想问一下。 - Brandon Moore
那么,关闭记录集的另一个原因是什么呢?当记录集将立即被设置为“无”(无论是显式地还是通过超出范围)时,是否有其他原因需要关闭记录集? - Brandon Moore

2

我需要写很多文件。如果我在每个文件写完后没有关闭连接,那么在后续的文件末尾会出现多余的垃圾内容。

fsT.Close

跟随着
fsT.Open

“刷新”输出流。因此,当我保存一个新文件时,它是“干净的”。


1

在编程中,您可能会遇到ODBC或OLEDB池问题,这会保持连接打开并占用池槽:

连接泄漏的常见原因包括:

ADO连接和Recordset对象没有被实际关闭。如果您不明确关闭它们,它们将不会释放到池中。这可能是连接泄漏最常见的原因。

您创建的ADO对象(特别是Connection对象)没有被明确释放。明确释放您创建的对象只是良好的编程实践。如果您分配了内存,请释放它。根据您使用的语言,让变量超出范围可能会导致它被释放或未被释放。

请参阅Microsoft数据访问组件中的池化

如果涉及到.Net Interop,则需要小心:有很多关于由于.Net垃圾回收下COM对象(或包含的对象)释放方式的惰性而引起的问题的警告。


1
据我所知,如果 Recordset 没有使用自己的 Connection 打开,那么池化不是问题。 - Bob77
好的,我明白了。我只使用过已经传递连接对象的记录集,实在记不清可以在没有传递连接对象的情况下打开记录集。谢谢。 - Brandon Moore

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