I am trying to delete a SQLite database file from my C# application. The same application performs multiple RW queries to the DB by creating and disposing a new connection each time.
When trying to delete the DB, (on a moment when I can assure the program is not querying the DB, thus no active connections) I was facing the error:
IOException: The process cannot gain access to <filename> because is being used by another process.
I have investigated for several hours: my code, SO questions, using procmon and resmon to be sure that my process was the only one holding an active handle to the file.
After all this, I determined that the DB file is not being closed correctly whenever I create a DB connection. Explanation follows:
I have the following function to perform a query and load the results into a 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;
}
}
Well, using SysInternals handle.exe
in an infinite loop (running every second) and debugging the program step-by-step using Visual Studio's Debugger I found out that the file handle to my DB file is not being closed despite:
- Calling
Close
- Calling
Dispose
- Getting out of the
using
scope - Killing all pools
- Executing GC and waiting for it to finish
I really need to delete my DB file from inside the code but I cannot as the file handle is never closed.
How could I solve this?
EDIT 1:
- Using .NET Winforms Application with
System.Data.SQLite
- Already tried adding
Pooling=false
to the connection string.
System.Data.SQLite
. – Fraction