2

I am having an issue when I create a file (an Sqlite Database) inside a long-running Task I cannot properly delete it if the task was cancelled. It throws an IOException about being used in another process, I assume the other process is the Task.

It does properly delete if I don't cancel the task and let it complete.

 var cancellationTokenSource = new CancellationTokenSource();
 var cancellationToken = cancellationTokenSource.Token;

 string dbFilePath = @"C:\test.db";

 Task.Factory.StartNew(() => 
     {
          PopulateDatabase(dbFilePath);
     }, cancellationToken).ContinueWith((result) =>
     {
          GC.Collect();
          File.Delete(dbFilePath);   // <--- Used in other process exception occurs here
     }, TaskScheduler.FromCurrentSynchronizationContext()  // Called from a GUI thread
 );

 cancellationTokenSource.Cancel(); // This occurs after the task is running

 // I use using blocks in here, so the proper dispose methods should be called.
 private void PopulateDatabase(string filePath) {
     using(var conn = new SQLiteConnection(@"Data Source="+filePath+";")) {
         // Do a bunch of work
     }
 }

I even tried to modify PopulateDatabase to take in the CancellationToken and exit gracefully, but the same error occurs.

 private void PopulateDatabase(string filePath, CancellationToken cancelToken) {
     using(var conn = new SQLiteConnection(@"Data Source="+filePath+";")) {
         // Do a bunch of work
         while(true) {
             if (cancelToken.IsCancellationRequested)
             {
                  return; // I assume this calls the appropriate Dispose methods
             }
         }
     }
 }
Moop
  • 3,414
  • 2
  • 23
  • 37

1 Answers1

-1

I had a similar problem and calling GC.Collect() alone will not always help as it starts the garbage collection in the background thread, so it returns immediately.

Try calling

GC.WaitForPendingFinalizers();

after GC.Collect().

VladL
  • 12,769
  • 10
  • 63
  • 83