Какая строка кода все еще использует файл и не освобождает его?

Я использую этот код для создания файла Excel и заполняю его данными:

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

После его завершения я вызываю функцию для удаления папки изображений. Функция «delete ()» выдает сообщение об ошибке:

изображение все еще используется

Когда я комментирую вышеуказанный код, ошибка не возникает. В настоящее время я использую этот хак для решения моей проблемы:

 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 } } 

Поэтому я даю возможность продолжать повторять снова и снова. Но это занимает примерно 15 секунд, пока «эта штука» не выпустит изображения, и приложение не сможет удалить папку, в то время как все приложение заморожено. Какая строка кода удерживает изображения (изображение)?

Вместо того, чтобы использовать Image.FromFile для получения изображения, вы должны использовать поток для чтения в копии изображения, а затем использовать эту копию. Проблема с Image.FromFile заключается в том, что он открывает ваш файл изображения по ссылке, чтобы никакая другая операция не могла его записать, пока ваше приложение не перестанет его использовать. Это, в основном, поток, который никогда не закрывается, пока он не будет полностью недоступен или вы вручную. .Dispose() объект объекта.

Итак, измените эту строку:

 var ImageToPutInReport = Image.FromFile(imagePath); 

К этой строке:

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

Из этой ссылки в Image.FromFile(string filename) указано, что The file remains locked until the Image is disposed. и вы нигде не рассеиваете изображение.

Вот что вызывает вашу проблему.

Эта строка:

 var ImageToPutInReport = Image.FromFile(imagePath); 

Будет держать ваше изображение открытым и заблокированным до тех пор, пока вы его не уничтожите (что, поскольку вы не выполняете явно, не произойдет, пока сборщик мусора не решит: те должны быть теми 15 секундами, которые вы наблюдаете при повторной попытке) … поэтому я ' d измените этот блок на:

 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: Как я уже упоминал выше, и как отметил @ScottChamberlain в комментариях, изображение может быть добавлено как ссылка (а не как копия), поэтому вы выбрали бы изображение, указанное в коллекции. если это так , мы можем разблокировать файл, создав копию (это должно освободить файл), а затем удалите копию позже, когда мы закончим с нашим пакетом … что-то вроде:

 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(); 
  • Откройте один рабочий лист (одна вкладка) из огромного файла excel в веб-браузере, используя c # asp.net / MVC
  • Частичная загрузка Excel EPPlus C #
  • почему openfiledialog вызывает excel для добавления в процессы диспетчера задач?
  • Запись ячейки в Excel из C ++ - не указано значение, ячейка пуста
  • Экспорт в Excel с использованием OpenXML и C #, целых чисел и даты
  • Использование VSTO в автономном приложении для доступа к листам Excel
  • Проверка данных Excel через веб-службу или подключение к SQL Server
  • Сохранить документ Excel в ASP.NET
  • Как создать оглавление для файла Excel, сгенерированного C #?
  • Excel: создание раскрывающегося списка в Xml Spreadsheet
  • Получение диапазона именованной области в Excel через C # .net
  • Interesting Posts

    Удалите все строки, если они дублируются в excel – VBA

    Генерировать EXCEL из XML с помощью XSLT

    Как создать диаграмму LineMarkers из динамических строк и фиксированное число столбцов

    Каждый третий столбец, связанный друг с другом

    Как отфильтровать таблицу Excel на основе значений в столбце с другой таблицей?

    Добавление формулы в ячейку из кода VBA

    Как динамически изменять диапазон диаграмм в раскрывающемся списке в Excel?

    Сохранение рабочих таблиц в формате CSV

    PHPExcel не отображает все строки, используя php

    Windows (ThisWorkbook.Name) .Visible = True вызывает ошибку в файлах с автоматическим восстановлением Excel

    Предотвращение открытия источников данных Чтение только при обновлении сводной таблицы с внешним подключением

    Отображать текст как значения в сводной таблице

    Нужно сделать набор графиков в excel с помощью макроса vba

    Добавление текста формулы в конкретную ячейку на пандах

    Создание базы данных с использованием Access?

    Давайте будем гением компьютера.