7

I am developing a C# application with its backend as sqlite. In my application I have a button for cleaning the database (deleting the .db file and creating it again with some initial data). Sometimes when I try to delete the db it says it cannot be deleted because it is being used by another process. Before deleting it I am using close connection, dispose and clear pool functions. Even then it throws the same exception. Here is my code:

string targetDataBaseFilePath = Path.Combine(dataDirectoryPath, "local.db");               
ThingzDatabase.Create(targetDataBaseFilePath, "touchdb");

In the create function I define the following code, from where I get the error:

if (File.Exists(DatabaseFileName))
{
    try
    {
        ThingzDatabase.localdb.conn.Close();
        ThingzDatabase.localdb.conn.Dispose();
        SQLiteConnection.ClearAllPools();
    }
    catch (Exception)
    {
    }
    File.Delete(DatabaseFileName); //error throws from here.                       
}

How can I prevent the error from being thrown?

Matthew Strawbridge
  • 19,940
  • 10
  • 72
  • 93
Sangeetha
  • 601
  • 3
  • 12
  • 26

7 Answers7

5
FileInfo fi = new FileInfo(DatabasePath);
try
{
    if (fi.Exists)
    {
        SQLiteConnection connection = new SQLiteConnection("Data Source=" + DatabasePath + ";");
        connection.Close();
        GC.Collect();
        GC.WaitForPendingFinalizers();
        fi.Delete();
    }
}
catch(Exception ex)
{
    fi.Delete();
}

DatabasePath is your database file path

Akshay Mishra
  • 1,535
  • 2
  • 15
  • 14
2
ThingzDatabase.localdb.conn.ClearAllPools(); 

should be the call for that line I believe.

Travis J
  • 81,153
  • 41
  • 202
  • 273
  • This definitely needs more voices. In my case I am doing some tests with Setup/Teardown and relying on GC calls seemed really hacky. Note that the API seems to have change since then, it is now a static method on SQLiteConnection, you now call it like that: `SQLiteConnection.ClearAllPools()` – Luke Marlin Apr 04 '19 at 08:56
2

I ended up just asking the question myself. The solution was to let garbage collection run for a bit.

Community
  • 1
  • 1
Tom Cerul
  • 1,773
  • 2
  • 13
  • 27
1

I beleive you still haven't disposed something returned from API.

Which sqlite wrapper you use? You are quoting use of your custom functions, what do they do?

Basilevs
  • 22,440
  • 15
  • 57
  • 102
  • I had a reference to a DB connection that wasn't disposed properly. Once I took care of that, this issue was resolved for me. Good call. – Jacob Robbins May 22 '18 at 14:05
  • I had the same issue, found out I did not use "using" for one SQLiteCommand in ADO.NET. – Petr May 25 '20 at 08:08
1

In connection string use this Pooling=False; I had the same problem with pooling on.

Tommix
  • 133
  • 1
  • 2
  • 10
-1

I see a lot working with processes. But sqlite has a method for it. VACUUM

The VACUUM command rebuilds the database file, repacking it into a minimal amount of disk space.

https://sqlite.org/lang_vacuum.html

eL-Prova
  • 1,084
  • 11
  • 27
-1

You can use a procmon like this one by Mark Russinovich.
Then you can filter the display on the basis of the filename.
Once this is done, you can see exactly which process is locking this file, and debug accordingly.

Lelouch Lamperouge
  • 8,171
  • 8
  • 49
  • 60