Как обнаружить, если загрузка изображения выдаст исключение OutOfMemory в.NET?

У меня есть приложение записанное использование.NET 3,5 SP1, который загружает изображения с внешнего сайта и отображает их к конечным пользователям. На редком ocassions мои пользователи сталкиваются с ошибками OutOfMemory, потому что они загружают огромные изображения. Иногда необработанные данные, связанные с этими изображениями, являются большими, но чаще, размеры изображений огромны. Я понимаю, что никогда не могу мочь обойти то, что эти ошибки OOM брошены для конкретных изображений. Было бы ОЧЕНЬ полезно, однако, если я мог бы так или иначе определить, приведет ли загрузка конкретного изображения к проблеме OOM, прежде чем я попытаюсь загрузить изображение.

Данные для изображений загружаются в Поток, и затем само изображение превращено в Систему. Рисование. Изображение путем звонка Системе. Рисование. Изображение. FromStream (поток). У меня нет опции хранения этих изображений на диске сначала. Они должны быть загружены через память.

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

5
задан Keith 7 July 2010 в 20:40
поделиться

6 ответов

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

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

1
ответ дан 14 December 2019 в 01:01
поделиться

Для проверки наличия памяти можно использовать класс MemoryFailPoint.

Best

4
ответ дан 14 December 2019 в 01:01
поделиться

Вы можете посмотреть на этот вопрос и посмотреть, поможет ли он: Как мне надежно получить размеры изображения в .NET без загрузки изображения?

Идея заключалась бы в загрузке только части всего изображения (в частности, заголовка), чтобы вы могли читать метаданные. Затем вы можете использовать эту информацию, чтобы определить размер изображения, и запретить ему полную загрузку, если вы видите, что оно слишком велико.

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

1
ответ дан 14 December 2019 в 01:01
поделиться

Я уже согласился с ответом @Vagaus , но я хотел добавить, что вам следует выделить буфер только один раз и попытаться использовать его повторно. Если вы постоянно выделяете и освобождаете большой буфер, вы обязательно столкнетесь с проблемой OOM из-за фрагментации кучи.

1
ответ дан 14 December 2019 в 01:01
поделиться

У вас проблема с курицей и яйцом. Чтобы сделать какое-то предположение, нужно знать размер изображения. Вы не знаете размер, пока не загрузите его.

Это все равно бесполезно. Получите ли вы OOM действительно, зависит от того, насколько фрагментировано адресное пространство виртуальной памяти. И это не легко найти в Windows. Требуется функция API HeapWalk (), и использовать эту функцию нездорово. Посмотрите мелкий шрифт в статье библиотеки MSDN. Особенно плохо в управляемой программе, не используйте ее.

Обратите внимание, что это исключение OOM - это не тот тип OOM, который вы получили бы, когда использовали слишком много управляемой памяти. На самом деле это исключение GDI +, и вы можете легко от него избавиться. Просто перехватите исключение и отобразите сообщение «К сожалению, не удалось».

Если вы каким-то образом знаете размер передней части, то можете с уверенностью предположить, что ширина * высота * 4> 550 МБ не будет работать в 32-битной программе. Этот предел быстро снижается после некоторой пробежки.

1
ответ дан 14 December 2019 в 01:01
поделиться

Если вы загружаете изображения с внешнего сайта, и внешний сайт устанавливает HTTP-заголовок Content-Length, вы можете оценить, поместится ли изображение в память еще до того, как начнете загружать поток...

1
ответ дан 14 December 2019 в 01:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: