简体   繁体   中英

C# program freezes when I try to delete file which is being used

researched many topics about this exception, no luck. my simple code:

            string t = Path.GetTempFileName();
            t = t.Remove(t.Length - 11, 11);
            var q = Directory.EnumerateFiles(t, "tmp????.tmp");

            var f = q.ToList();
            for (int i = 0; i < q.Count(); i++)
            {
                //      if (Helper.CanReadFile(f[i]))
                try
                {
                    File.Delete(f[i]);
                }
                catch (IOException)
                {

                    break;
                }

            }

I ran this code in Closing event of mainwindow. So it deletes several files, gets into exception, then to "break" statement, and then.. somewhere. Just freezes and pausing debugger leads to nothing. I tried several pieces of code to find whether the file is used before deletion, but it gets an exception inside this code (like Helper.CanReadFile) and halts program flow there. I dont really have to delete all files, but I need to stop that freezing. How can I work with this exception so that wont freeze my program?

some edit with breakpoints and info for most of them.

1) got an exception http://imgur.com/a/k6of3

2) first step from it, nothing much http://imgur.com/a/FvWjz

3) went back to dispose http://imgur.com/a/LMdiA

4) went back to event method http://imgur.com/a/FlIUf

5) which was called from onclose http://imgur.com/a/YQUrZ

6) after that it loops here for a while (I use global hotkey) http://imgur.com/a/0qjdf it goes off after ~10 loops with msg = 130. and my program closes fine if I remove file deletion part.

7) Freezed part (no code is running message) http://imgur.com/a/WeEGj

When deleting files you can try this:

To run this code on a background Thread you can do several things:

Change to private async Task DeleteAllTempFiles() and call it without await !

OR

new Thread(() => { DeleteAllTempFiles(); }).Start();

private void DeleteAllTempFiles()
{
   try
   {
       //Get the temp Path
       DirectoryInfo tempDir = new DirectoryInfo(Path.GetTempPath());
       //Get all matching files
       List<FileInfo> tempFiles = tempDir.GetFiles("tmp????.tmp", SearchOption.AllDirectories).ToList();

       //Collect all files that fail to delete
       List<FileInfo> cannotDelete = new List<FileInfo>();

       //Delete Files:
       DeleteFiles(tempFiles, out cannotDelete);

       //Show what failed (and retry or whatever)
       string message = "Cannot delete the following file(s):";
       cannotDelete.ForEach(file => message += "{file.FullName}{Environment.NewLine}");
       MessageBox.Show(message, "Result");
   }
   catch (Exception ex)
   {
       Debug.Fail(ex.Message);
   }
}

private void DeleteFiles(List<FileInfo> filesToDelete, out List<FileInfo> failedToDelete)
{
   foreach(FileInfo file in filesToDelete)
   {   
      try
      {
         file.Delete();
      }
      catch (IOException ioEx)
      {
         failedToDelete?.Add(file); //<-- Check if failedToDelete != null !!!
         //This will always happen.
         //Since its not "hard fail" you should log it but keep goin !
         //MessageBox.Show($"IO-Exception: {ioEx.Message}");
      }
      catch (Exception ex)
      {
         MessageBox.Show($"Exception: {ex.Message}");
      }
   }
}

If you want to work with the files you can't delete you can process them with this: How do I find out which process is locking a file using .NET?

For a fast check what locks your files you can use: OpenedFilesView or Windows Sysinternals Process Explorer

Maybe you can try to set some attributes... Maybe you can get access with this:

在此处输入图片说明

Sorry for the bad size of the image ..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM