Search code examples
c#asp.net-mvcdelete-filefile-in-use

File remains in use until client refreshes page


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.


Solution

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