Search code examples
c#multithreadingbackgroundworkerdelete-fileioexception

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();
        }
    }
}

Solution

  • 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();
    }