Pandi
Pandi

Reputation: 471

How to delete a file which is used in another thread or process in c#

Here, i have a some format file which contains 2 folders and some xml files in that folders.While opening that file i extract that file in temporary location like appdata.

Then read each and every file and rendered some UI elements based upon the saved file texts.While opening i will show the waiting indicator box and that loaded process are doing in background with dispatcher.

If i want to abort that operation click abort and not needed to perform any operations(Render UI elements).Here i will delete that temporary location it will show "the process cannot access this file because it is used by another process" exception.May i know how to delete that file or which process is used that file?

Here is my code:

I made an edit, Using CancellationToken for abort all methods.

var backGroundWorker = new CancelSupportedBackgroundWorker { WorkerSupportsCancellation = true };
CancellationTokenSource source = new CancellationTokenSource(); 
AlertBox = new AlertBox { IsBusy = true };
AlertBox.WaitingText = Loading;
AlertBox.WaitingHeaderText = Loading Indicator;
AlertBox.AbortButton.Click += (obj, arg) =>
{
    App.Current.Dispatcher.Invoke(new Action(() =>
    {
        string tempDir = C:\Users\Lenovo\AppData + FileAndDirectoryConstants.TempDirFolder;
        if (Directory.Exists(tempDir))
        {
            Directory.Delete(tempDir, true);
        }
      }));

GC.Collect();
source.Cancel();
GC.WaitForPendingFinalizers();
backGroundWorker.CancelAsync();
backGroundWorker.Abort();
backGroundWorker.Dispose();
}

backGroundWorker.DoWork += (obj, arg) =>
{
    try
    {
        RenderUiElements(fileName,(CancellationToken)arg.Argument);
    }
    catch (ThreadAbortException)
    {
        Dispatcher.Invoke(() =>
        {
            AlertBox.IsBusy = false;
        }, System.Windows.Threading.DispatcherPriority.Background);
        arg.Cancel = true;
    }
};
backGroundWorker.RunWorkerCompleted += (obj, arg) =>
{
    AlertBox.isBusy = false;
}
backGroundWorker.RunWorkerAsync(source.Token);

private void RenderUiElements(string fileName,CancellationToken token)
{
    try
    {
        if(token != default(CancellationToken))
           if(token.isCancellationRequested)
              return;
        App.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(
        delegate ()
        {
            using (fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None))
            {                                
                LoadReport(fileStream, fileName,token);
            }
        }));
    }
    catch (ThreadAbortException)
    {
        return;
    }
    finally
    {
        if (fileStream != null)
        {
            fileStream.Close();
            fileStream.Dispose();
        }
    }
}

Upvotes: 0

Views: 1638

Answers (2)

Pandi
Pandi

Reputation: 471

Finally, I found that solution,

Here the Filestream object is doesn't properly disposed which is disposed only after LoadReport method completely. If i click abort while doing LoadReport the filestream doesn't disposed.So that error occurred.

So clear the Filestream object in LoadReport() method.

private void LoadReport(stream filestream,CancellationToken token)
{
 filestream.Close();
 filestream.Dispose();
}

Upvotes: 0

Caius Jard
Caius Jard

Reputation: 74605

There are only 2 ways you can delete a file in use by another process

  • force all file handles currently open on a file to be closed, then delete the file
  • P/Invoke the Windows MoveFileEx function, and use the MOVEFILE_DELAY_UNTIL_REBOOT flag, with a NULL destination name. This will delete the file when you reboot.

I'd recommend you perform the latter, as doing the former is nasty and could cause serious problems for other running apps. For more info on the latter, see http://www.pinvoke.net/default.aspx/kernel32.movefileex

Upvotes: 1

Related Questions