我正在尝试从我的C#应用程序中删除一个SQLite数据库文件。同一个应用程序通过每次创建和释放一个新的连接来执行对DB的多次RW查询。
当尝试删除数据库时,(在我可以确保程序没有查询数据库的时刻,因此没有活动连接)我面临的错误:
IOException: The process cannot gain access to <filename> because is being used by another process.
我调查了几个小时:我的代码,所以问题,使用procmon和resmon来确保我的进程是唯一一个持有文件活动句柄的进程。
经过这一切,我发现每当我创建一个DB连接时,DB文件没有被正确关闭。
我使用以下函数执行查询并将结果加载到DataTable
中:
public DataTable PerformQuery(string query) {
try {
DataTable table = new DataTable();
using(SQLiteConnection connection = new SQLiteConnection(connString)) {
SQLiteCommand cmd = connection.CreateCommand();
cmd.CommandText = query;
connection.Open();
if (!query.StartsWith("SELECT")) {
cmd.ExecuteNonQuery();
} else {
SQLiteDataReader reader = cmd.ExecuteReader();
FillTable(reader, table);
}
// Despite using the using scope, close and dispose the connection manually
connection.Close();
connection.Dispose();
}
// Kill all pools and call GC
SQLiteConnection.ClearAllPools();
GC.Collect();
GC.WaitForPendingFinalizers();
return table;
} catch (Exception ex) {
// Handle error... (not relevant)
return null;
}
}
在无限循环中使用SysInternals handle.exe
(每秒运行一次)并使用Visual Studio的调试器逐步调试程序后,我发现DB文件的文件句柄没有关闭,尽管:
- 呼叫
Close
- 呼叫
Dispose
- 退出
using
范围 - 正在终止所有池
- 正在执行GC并等待其完成
我真的需要从代码内部删除我的DB文件,但我不能,因为文件句柄从未关闭。
我该怎么解决这个问题?
编辑1:
- 在
System.Data.SQLite
中使用. NET Winforms应用程序 - 已尝试将
Pooling=false
添加到连接字符串。
1条答案
按热度按时间amrnrhlw1#
您是否也尝试过关闭SQLiteCommand?