Исключение GDI + при сохранении изображения в формате PNG
Приложение ASP.NET на моем сервере начинает бросать исключение GDI + после запуска в течение нескольких дней. После перезапуска сервера все работает нормально в течение нескольких дней, а затем внезапно это исключение происходит снова. После первого раза это происходит каждый раз, когда я пытаюсь сохранить изображение PNG, пока я не перезапущу его снова.
Когда я пытаюсь сохранить изображение в формате JPEG, он отлично работает.
Когда я запускаю этот код из моего проекта, он терпит неудачу:
var path = @"C:\Project\images\logo.png";
var image = Image.FromFile(path);
using (var ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Png); // Fails here on GDI+ exception.
//image.Save(ms, ImageFormat.Jpeg); // JPEG works somehow
}
Снова: когда я перезапускаю удаленный рабочий стол и запускаю этот код, он работает в течение нескольких дней и в какой-то момент внезапно начинает терпеть неудачу снова и снова.
Я пробовал:
-
Сделать консольное приложение с тем же кодом и запустить его в RDP, где находится проект. Он работал нормально!
-
Множество различных вариантов кодов, которые были предложены более чем в 10 статьях, которые я прочитал по этой теме.
-
GCI.Collect() - без помощи.
-
Проверяют все папки, у которых есть права на запись (возможно, что-то есть с IIS?).
-
Далее.
Я думаю, что это должна быть какая-то конфигурация, которая внезапно меняется из-за чего-то, и я не могу понять, что это может быть.
Ответы
Ответ 1
После перезапуска сервера все работает отлично в течение нескольких дней, а затем внезапно это исключение происходит, и после первого раза это произойдет, каждый раз, когда я пытаюсь сохранить изображение PNG, я снова перезапущу его.
Звучит как утечка памяти для меня. С какой версией .NET это скомпилировано? Какая серверная ОС работает?
Вы можете начать с включения изображения в блок использования:
var path = @"C:\Project\images\logo.png";
using (Image image = Image.FromFile(path))
{
using (var ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Png);
}
}
Эта ссылка Я считаю, относится к вашему делу.
Ответ 2
Он выдает ошибку GDI +, потому что один из ваших объектов не расположен, поэтому лучше удаляйте используемый объект.
Если вы получаете эту ошибку, я могу сказать, что ваше приложение не имеет права на запись в какой-либо каталог.
GDI + ограничивает высоту изображения до 65534
Всегда рекомендуется использовать инструкцию using. Который никогда не забывает распоряжаться объектом, даже если код генерирует исключение.
var path = @"C:\Project\images\logo.png";
using (Image image = Image.FromFile(path))
{
using (var ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Png); //fails here on GDI+ exception.
//image.Save(ms, ImageFormat.Jpeg); //Jpeg Works somehow
}
}
Метод FromFile блокирует файл, поэтому для чтения изображения используйте метод Image.FromStream():
byte[] bytes = System.IO.File.ReadAllBytes(filename);
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes);
using (var ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Png); //fails here on GDI+ exception.
//image.Save(ms, ImageFormat.Jpeg); //Jpeg Works somehow
}
Ответ 3
В принципе, если у вас есть одноразовые объекты... Утилизируйте их!
Изображение одноразовое, и в качестве растрового изображения оно использует ресурсы Windows.
Если вы не распоряжаетесь, ресурсы Windows не освобождаются, пока вы не отключите приложение. Таким образом, вам нужно избавиться от любого созданного образа.