GDI + System.Drawing.Bitmap выдает ошибку Параметр недействителен периодически - PullRequest
13 голосов
/ 25 сентября 2008

У меня есть некоторый код C # в приложении ASP.Net, который делает это:

Растровое изображение bmp = новое растровое изображение (1184, 1900);

И иногда выдает исключение "Параметр недействителен". Сейчас я гуглюсь и, очевидно, GDI + печально известен тем, что выбрасывает случайные исключения, и у многих людей была эта проблема, но ни у кого нет решения! Я проверил систему, и она имеет много оперативной памяти и места подкачки. Теперь в прошлом, если я делаю «iisreset», тогда проблема исчезнет, ​​но она вернется через несколько дней. Но я не уверен, что вызвал утечку памяти, потому что, как я уже сказал выше, есть много оперативной памяти + swap free.

У кого-нибудь есть какие-нибудь решения?

Ответы [ 6 ]

10 голосов
/ 05 октября 2008

Прекратите использовать GDI + и начните использовать классы визуализации WPF (.NET 3.0). Это основная очистка классов GDI + и настроенная на производительность. Кроме того, он устанавливает «цепочку растровых изображений», которая позволяет легко и эффективно выполнять несколько действий с растровым изображением.

Узнайте больше, прочитав о BitmapSource

Вот пример начала с пустого растрового изображения, ожидающего получения нескольких пикселей:

using System.Windows.Media.Imaging;
class Program {
    public static void Main(string[] args) {
        var bmp = new WriteableBitmap(1184, 1900, 96.0, 96.0, PixelFormat.Bgr32, null);
    }
}
6 голосов
/ 08 октября 2008

Для тех, кому интересно, я собираюсь использовать решение - библиотеки Mono.Cairo из дистрибутива mono C # вместо использования system.drawing. Если я просто перетащу файлы mono.cairo.dll, libcairo-2.dll, libpng13.dll и zlib1.dll из версии Windows mono в ту же папку, что и мой исполняемый файл, то я смогу работать в Windows с помощью Visual Studio 2005 и все работает хорошо.

Обновление - я выполнил вышеупомянутое, стресс-тестирование приложения, и теперь все работает гладко и использует для загрузки до 200 МБ оперативной памяти. Очень счастлив.

3 голосов
/ 05 октября 2008

Все, что я видел на сегодняшний день в моем контексте, связано с утечками памяти / утечками дескрипторов. Я рекомендую вам по-новому взглянуть на ваш код.

Что действительно происходит, так это то, что изображение будет располагаться в произвольном порядке в будущем, даже если вы создали его в предыдущей строке кода. Это может быть из-за утечки памяти / дескриптора (очистка моего кода, кажется, улучшает, но не полностью решает эту проблему).

Поскольку эта ошибка возникает после того, как приложение некоторое время использовалось, иногда использует много памяти, иногда нет, я чувствую, что сборщик мусора не подчиняется правилам из-за некоторых специальных настроек, связанных со службами, и именно поэтому Microsoft моет руки от этой проблемы.

http://blog.lavablast.com/post/2007/11/The-Mysterious-Parameter-Is-Not-Valid-Exception.aspx

1 голос
/ 25 сентября 2008

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

new Bitmap (x, y) почти просто нужно выделить память - при условии, что ваша программа каким-то образом не повреждена (есть ли какой-нибудь небезопасный код, который может повредить кучу), тогда я бы начал с этого выделения терпит неудачу. Потребность в непрерывном блоке - то, как казалось бы маленькое распределение могло потерпеть неудачу. Фрагментация кучи - это то, что обычно решается с помощью специального распределителя - я не думаю, что это хорошая идея в IIS (или возможно).

Чтобы увидеть, какую ошибку вы получаете из памяти, попробуйте просто выделить гигантский битовый образ в качестве теста - посмотрите, какую ошибку он выдает.

Одна стратегия, которую я видел, заключается в том, чтобы предварительно выделить несколько больших блоков памяти (в вашем случае растровые изображения) и рассматривать их как пул (получить и вернуть их в пул). Если они вам нужны только в течение короткого периода времени, вам, возможно, удастся просто оставить несколько в памяти и поделиться ими.

0 голосов
/ 02 декабря 2013

Классы в пространстве имен System.Drawing не поддерживаются для использования в службе Windows или ASP.NET

Поддерживаемую альтернативу см. В Windows Imaging Components ( msdn ), родной библиотеке, на которой, как ни странно, System.Drawing основан.

0 голосов
/ 29 сентября 2008

Я только что получил ответ от службы поддержки Microsoft. Видимо, если вы посмотрите здесь:

http://msdn.microsoft.com/en-us/library/system.drawing.aspx

Вы можете увидеть, что это говорит: «Классы в пространстве имен System.Drawing не поддерживаются для использования в службе Windows или ASP.NET. Попытка использовать эти классы в одном из этих типов приложений может привести к непредвиденным проблемам, таким как уменьшение производительность службы и исключения во время выполнения. " Таким образом, они в основном моют руки от этой проблемы. Похоже, они признают, что этот раздел .Net Framework ненадежен. Я немного разочарован.

Далее - кто-нибудь может порекомендовать подобную библиотеку, чтобы открыть файл gif, наложить некоторый текст и снова сохранить его?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...