Подтвердить что ты не робот

GDI + System.Drawing.Bitmap дает ошибку Параметр недействителен с перерывами

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

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

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

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

4b9b3361

Ответ 1

Прекратите использование 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);
    }
}

Ответ 2

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

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

Ответ 3

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

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

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

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

Ответ 4

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

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

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

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

Ответ 5

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

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

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

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

Ответ 6

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

Для поддерживаемой альтернативы см. Компоненты обработки изображений Windows (msdn), родную библиотеку, которая по иронии судьбы основана на System.Drawing.