SQLite DB文件句柄从未关闭C#

zpjtge22  于 2023-02-23  发布在  SQLite
关注(0)|答案(1)|浏览(230)

我正在尝试从我的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添加到连接字符串。
amrnrhlw

amrnrhlw1#

您是否也尝试过关闭SQLiteCommand?

using (SQLiteConnection connection = new SQLiteConnection(connString)) {
    using (SQLiteCommand cmd = connection.CreateCommand()){
        // do stuff here
    }
}
SQLiteConnection.ClearAllPools();
GC.Collect();
GC.WaitForPendingFinalizers();

相关问题