【问题标题】:Should RecordSet object be nulified in VB.NET?RecordSet 对象是否应该在 VB.NET 中被取消?
【发布时间】:2017-09-12 13:43:46
【问题描述】:

我正在将旧的 VB6 应用程序转换为更新的 VB.NET 应用程序,升级后经常看到这 3 行:

rs.Close()
'UPGRADE_NOTE: Object rs may not be destroyed until it is garbage collected. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6E35BFF6-CD74-4B09-9689-3E1A43DF8969"'
rs = Nothing

其中 rs 是这样的 RecordSet 类型:

Dim rs As ADODB.Recordset
rs = New ADODB.Recordset

应该是最后一个

rs = Nothing 

线还存在吗?或者

rs.Close() 

够了吗?

【问题讨论】:

  • 你应该升级的东西之一是 ADODB 到 ADONET
  • 好消息。你在说这个:github.com/AlexGascon/ADODBNET/blob/master/ADODBNET/ADODBNET.vb 吗? @Plutonix
  • @Vlad: 不,这个:docs.microsoft.com/en-us/dotnet/framework/data/adonet/index 并且你应该使用Using-语句来实现IDisposable 的对象,比如DbDataReader
  • ADONET 是 NET 框架的一部分。 Access 和 SQL Server DBProvider 是内置的(System.Data 命名空间)。如果您使用其他东西(MySQL,SQLite)他们有自己的提供者,但仍然使用来自System.Data 的一些与数据库无关的工具(Datatable 等)
  • RecordSet 是一个 COM 对象,它的 RCW 的终结器需要运行才能真正销毁它。将其设置为 null 实际上会延迟,因为对象被引用的时间比必要的长一点。您不会注意到,抖动本身已经删除了发布版本中的代码。但是,如果 rs 是类对象中的一个字段,可以存在一段时间,那么将其设置为 Nothing 可以加快速度。警告真正试图告诉您的是底层 COM 对象的寿命将比以前更长。在 GC 运行不够频繁的应用中不好。

标签: vb.net vb6 visual-studio-2005 vb6-migration


【解决方案1】:

使用 VB.Net,您几乎不会将对象设置为 Nothing。这在 VB6 时代很常见,但对于 .Net,它不再有用,并且在极少数情况下可能会产生积极的危害。你应该做的是使用 Try/Catch/Finally 块的Finally 部分(或速记的Using 块)来确保实现IDisposable 接口的对象有它们的Dispose() 函数在一个及时的方式,在旧 ADO 对象的情况下,Finally 块是调用.Close() 的地方。您特别希望为 ADO 连接对象执行此操作。

总而言之,rs = Nothing 行不应该存在,但 rs.Close() 本身也不够。

但这确实是一个附带问题。如果您要转换为 VB.Net,最好的办法是将原始 ADO 转换为更现代的 ADO.Net,这对于 VB.Net 来说更惯用。这意味着首先使用DataSetDataReader 而不是RecordSet。

最后,这也是检查您的查询并确保它们使用查询参数而不是字符串连接的好时机。希望您已经这样做了,但是那里有 很多 旧且易受攻击的经典 ASP 和 vb6 代码,而 .Net 迁移是填补这些漏洞的好时机。 Sql 注入可不是什么玩意儿。

【讨论】:

  • @DaveInCaz 现在好点了吗?
  • 另外...通读这篇文章,解释 #4 提到了 ADO 中的一个错误,它迫使您这样做以确保 RecordSet 和 Connection 以正确的顺序清理。所以至少在问题的背景下,rs = Nothing 在 vb6 时代是“需要的”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-29
  • 2016-04-09
  • 2016-06-25
  • 1970-01-01
  • 2021-09-30
  • 2011-04-12
相关资源
最近更新 更多