gpt4 book ai didi

vb.net - 一次性类引用

转载 作者:行者123 更新时间:2023-12-03 18:33:38 25 4
gpt4 key购买 nike

我在项目中经常使用简单的DataReader命令。
为了简化它,我创建了一个函数:

Public Function DataReaderFromCommand(ByRef uCn As SQLite.SQLiteConnection, ByVal uCommandText As String) As SQLite.SQLiteDataReader

Dim nCmdSel As SQLite.SQLiteCommand = uCn.CreateCommand
With nCmdSel
.CommandText = uCommandText
End With

Dim r As SQLite.SQLiteDataReader = nCmdSel.ExecuteReader

Return r

End Function


在我的项目中,我像这样使用它:

Using r As SQLite.SQLiteDataReader = DataReaderFromCommand(cnUser, "SELECT * FROM settings")
Do While r.Read
'do something
Loop
End Using'this should close the DataReader


在一种情况下,我需要删除数据库。但是,此操作失败,并显示错误“文件被另一个进程锁定”。

我试图找出问题所在,并且由于函数“ DataReaderFromCommand”而发生锁定。

有人看到我做错了什么/什么使数据库锁定了吗?

我认为在数据读取器的“最终使用”之后,还将处理SQLiteCommand,因此没有对数据库的进一步引用。

最佳答案

第一个问题是并非所有一次性用品都被丢弃。我们确信传递给该帮助程序的连接位于Using块中,但是由于该命令具有对该连接的引用,因此也需要将该命令处理掉:

Dim cmd As New SQLiteCommand(sql, dbcon)

即使您不使用重载的构造函数,也可以在某处设置连接属性以进行工作。这说明了此类“数据库帮助程序”方法的问题之一: DBConnectionDBCommandDBReader对象非常紧密地协同工作,但是它们是在具有不同作用域的不同方法中创建的,通常无法查看是否一切都被正确清理。
发布的代码将始终失败,因为未处置 DBCommand对象-扩展了 DBConnection-。但是,即使您进行了适当的清理,池也会使 DBConnection作为 jmcilhinney explains存活一段时间。这里有2个修复程序:
清除池
Using dbcon As New SQLiteConnection(LiteConnStr),
cmd As New SQLiteCommand(sql, dbcon)

dbcon.Open()
Dim n As Int32 = 0
Using rdr = cmd.ExecuteReader
While rdr.Read
' == DoSomething()
Console.WriteLine("{0} == {1}", n, rdr.GetString(0))
n += 1
End While

End Using

' Clears the connection pool associated with the connection.
' Any other active connections using the same database file will be
' discarded instead of returned to the pool when they are closed.
SQLiteConnection.ClearPool(dbcon)
End Using

File.Delete(sqlFile)

dbConcmd对象被“堆叠”到一个 Using语句中以减少缩进。
这将关闭并丢弃池中的所有连接(如果已为 Disposed)以及引用它们的任何对象。如果使用 Dim cmd ...,则需要明确处理它。
强制垃圾收集
我认为这要困难得多,但为了完整起见也包括在内。
Using dbcon As New SQLiteConnection(LiteConnStr),
cmd As New SQLiteCommand(sql, dbcon)
...
Using rdr = cmd.ExecuteReader
...
End Using
End Using

GC.WaitForPendingFinalizers()

File.Delete(sqlFile)

只要一切都已正确处理,这也将起作用。除非绝对必要,否则我不愿与GC混为一谈。这里的问题是清理将不仅限于DBProvider对象,而是任何已经处置并正在等待GC的对象。
第三种解决方法是关闭池,但是您仍然必须处置所有内容。

关于vb.net - 一次性类引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45872668/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com