1

I am attempting to delete image files from the server file system but I get a 'file in use by another process' error. I am trying to delete the image and it's associated thumbnail in one fowl swoop. I can get one to delete but the other will try and fail forever, as far as I've seen. However, if I refresh the page while it's looping through a try-catch, the operation succeeds immediately. I am accessing the files via ajax requests and API controllers (my site is mostly one page) when I load the page, but I am doing so with 'using' statements. This should close the handle after use, but it seems to be staying open. I have to get the files on the client side to be able to have the option to delete them(browser content manager), so I don't see how they are still in use. I load the thumbnail and use it's ID to get it's name from the database, and use the name to find it in the file system.

I have tried putting a try-catch in a loop and waiting for the last process to finish, but it never does, until I refresh the page. I also tried deleting one at a time with separate ajax requests, but it seems that if I have opened a file at all, I can't delete it (until I refresh the page).

Code for deleting file (method 1):

public static void DeleteFromFileSystem(string path)
{
     for (int i = 1; i <= 10000; ++i)
         {
         try
         {
             System.IO.File.Delete(path);
             break;
         }
         catch (IOException e) when (i <= 10000)
         {
             Thread.Sleep(3);
         }
    }
}

Code for deleting file (method 2):

public static void DeleteFromFileSystem(string path)
{
     using(FileStream f = System.IO.File.OpenWrite(path))
     {
          System.IO.File.Delete(path);
     }
}

Code for getting image (works fine, but could be the problem):

public static byte[] ImageToByte(string name, bool getThumbnail)
{
    if (name == null) name = "user.png"; //default profile picture
    string path = getThumbnail ? "wwwroot/ImgThumb/" : "wwwroot/ImgFull/";

    // this line is my best suspect
    System.Drawing.Image img = System.Drawing.Image.FromFile(path + name);

    byte[] b;
    using (MemoryStream mStream = new MemoryStream())
    {
         img.Save(mStream, img.RawFormat);
         b = mStream.ToArray();
         mStream.Close(); // I added this as a precautionary. It didn't help.
    }
    return b;
}

I expect that the images get deleted, but I get the 'file X cannot be accessed because it is in use by another process' error.

  • 1
    not tested, but calling `Dispose` on `img` (or better, wrapping it within a `using`) should do the trick – Gian Paolo May 18 '19 at 17:00
  • Method 2 won't work, as you are locking the file within the FileStream, then trying to Delete within the using. However Method 1 should.. You could try using FileInfo.Delete instead, but it sounds like something has kept the file open (perhaps IIS or local debugger - as you have said that refreshing the page clears the lock) – Radderz May 18 '19 at 17:02

1 Answers1

1

SOLVED - I added img.Dispose() after the using statement.

  • Really, always use `using` construct when you can, instead of explicitly call `Dispose`. with `using` dispose will be called even with an early return or an exception. Let the language and the compiler help you – Gian Paolo May 18 '19 at 21:01