What line of code is still using the file and not freeing it?

I use this code to create an Excel file and populate it with data:

using (ExcelPackage package = new ExcelPackage(fileInfo))
{
    ExcelWorksheet ws = package.Workbook.Worksheets.Add("Deltas");
    ExcelWorksheet ws2 = package.Workbook.Worksheets.Add("Images");
    ExcelWorksheet ws3 = package.Workbook.Worksheets.Add("Data Points");

    GenerateDataSheet(ws, true);
    GenerateDataSheet(ws3, false);

    // populate second worksheet with images
    var imagesLocations = SelectedSession.GetTests().Where(t => t.IsReference).Select(t => t.Location).OrderBy(t => t.DateCreated).ThenBy(t => t.Name).ToList();
    ws2.Column(2).Width = 58;

    for (int i = 0; i < imagesLocations.Count; i++)
    {
        ws2.Row(i + 1).Height = 305;

        ws2.Cells[i + 1, 1].Value = imagesLocations[i].Name;
        ws2.Cells[i + 1, 1].Style.VerticalAlignment = ExcelVerticalAlignment.Top;
        ws2.Cells[i + 1, 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.Right;

        var imagePath = imagesLocations[i].Tests.FirstOrDefault(t => t.IsReference).ImagePath;
        if (File.Exists(imagePath))
        {
            var ImageToPutInReport = Image.FromFile(imagePath);
            var image = ws2.Drawings.AddPicture(imagesLocations[i].Name, ImageToPutInReport);
            image.SetSize(375, 375);
            image.SetPosition(i, 0, 1, 0);
        }
    }

    package.SaveAs(fileInfo);
}

After the operation is completed, I call the function to delete the image folder. The delete () function throws an error message:

image is still in use

When I comment on the above code, the error does not occur. I am currently using this hack to fix my problem:

public static void DeleteSessionFolder(string session)
{
    try
    {
        if (Directory.Exists(baseSessionPath + session))
            Directory.Delete(baseSessionPath + session, true); // error pops here

    } catch (Exception e)
    {
        DeleteSessionFolder(session); // call it again
    }
}

So, I give a chance to keep repeating over and over. But it takes about 15 seconds until “this thing” releases the image and the application can delete the folder while the entire application is frozen. What line of code holds images (image)?

+4
3

, Image.FromFile , , . Image.FromFile , , , . , , , .Dispose() .

, :

var ImageToPutInReport = Image.FromFile(imagePath);

:

Image ImageToPutInReport;
using (FileStream stream = File.OpenRead(imagePath))
{
    ImageToPutInReport = Image.FromStream(stream);
}
+4

Image.FromFile(string filename) The file remains locked until the Image is disposed., .

.

+1

:

var ImageToPutInReport = Image.FromFile(imagePath);

, (, , , : 15 , )... :

using(var ImageToPutInReport = Image.FromFile(imagePath))
{
  var image = ws2.Drawings.AddPicture(imagesLocations[i].Name, ImageToPutInReport);
  image.SetSize(375, 375);
  image.SetPosition(i, 0, 1, 0);
}

, Image ( ) , , , GC .

PS: As I mentioned above, and as @ScottChamberlain noted in the comments, the image can be added as a link (and not as a copy), so you would select the image indicated in the collection. , if it is true. , we can unlock the file by creating a copy (this should free the file), and then delete the copy later when we are done with our package ... something like:

var imageList = new List<Image>();
using (ExcelPackage package = new ExcelPackage(fileInfo))
{
   /* ... */
         if (File.Exists(imagePath))
         {
            Image ImageToPutInReport;
            // Make a copy of the loaded image and dispose the original
            // so the file is freed
            using(var tempImage = Image.FromFile(imagePath))
               ImageToPutInReport = new Bitmap(tempImage);

            // Add to the list of images we'll dispose later 
            // after we're done
            imageList.Add(ImageToPutInReport);
            var image = ws2.Drawings.AddPicture(imagesLocations[i].Name, ImageToPutInReport);
            image.SetSize(375, 375);
            image.SetPosition(i, 0, 1, 0);
        }
   /* ... */
   package.SaveAs(fileInfo);
}
foreach(var img in imageList)
  img.Dispose();
imageList.Clear();
+1
source

All Articles