У меня есть приложение записанное использование.NET 3,5 SP1, который загружает изображения с внешнего сайта и отображает их к конечным пользователям. На редком ocassions мои пользователи сталкиваются с ошибками OutOfMemory, потому что они загружают огромные изображения. Иногда необработанные данные, связанные с этими изображениями, являются большими, но чаще, размеры изображений огромны. Я понимаю, что никогда не могу мочь обойти то, что эти ошибки OOM брошены для конкретных изображений. Было бы ОЧЕНЬ полезно, однако, если я мог бы так или иначе определить, приведет ли загрузка конкретного изображения к проблеме OOM, прежде чем я попытаюсь загрузить изображение.
Данные для изображений загружаются в Поток, и затем само изображение превращено в Систему. Рисование. Изображение путем звонка Системе. Рисование. Изображение. FromStream (поток). У меня нет опции хранения этих изображений на диске сначала. Они должны быть загружены через память.
Если бы у кого-либо есть какие-либо подсказки или предложения, которые позволили бы мне обнаруживать, что загрузка изображения приведет к исключению OOM, я был бы очень признателен за ее.
OutOfMemory - одно из тех исключений, когда у вас мало хороших параметры. Все, что однозначно предсказывает, что вы получите исключение, вероятно, должно просто сгенерировать исключение.
Я бы сказал, что лучше всего профилировать поведение и создать свой собственный набор правил прогнозирования или просто жестко указать максимальные размеры в своем приложении. Это некрасиво, но вы туда доберетесь.
Для проверки наличия памяти можно использовать класс MemoryFailPoint.
Best
Вы можете посмотреть на этот вопрос и посмотреть, поможет ли он: Как мне надежно получить размеры изображения в .NET без загрузки изображения?
Идея заключалась бы в загрузке только части всего изображения (в частности, заголовка), чтобы вы могли читать метаданные. Затем вы можете использовать эту информацию, чтобы определить размер изображения, и запретить ему полную загрузку, если вы видите, что оно слишком велико.
С другой стороны, похоже, что вам придется написать метод для декомпозиции двоичного файла каждого типа файла, который вы хотите обрабатывать.
Я уже согласился с ответом @Vagaus , но я хотел добавить, что вам следует выделить буфер только один раз и попытаться использовать его повторно. Если вы постоянно выделяете и освобождаете большой буфер, вы обязательно столкнетесь с проблемой OOM из-за фрагментации кучи.
У вас проблема с курицей и яйцом. Чтобы сделать какое-то предположение, нужно знать размер изображения. Вы не знаете размер, пока не загрузите его.
Это все равно бесполезно. Получите ли вы OOM действительно, зависит от того, насколько фрагментировано адресное пространство виртуальной памяти. И это не легко найти в Windows. Требуется функция API HeapWalk (), и использовать эту функцию нездорово. Посмотрите мелкий шрифт в статье библиотеки MSDN. Особенно плохо в управляемой программе, не используйте ее.
Обратите внимание, что это исключение OOM - это не тот тип OOM, который вы получили бы, когда использовали слишком много управляемой памяти. На самом деле это исключение GDI +, и вы можете легко от него избавиться. Просто перехватите исключение и отобразите сообщение «К сожалению, не удалось».
Если вы каким-то образом знаете размер передней части, то можете с уверенностью предположить, что ширина * высота * 4> 550 МБ не будет работать в 32-битной программе. Этот предел быстро снижается после некоторой пробежки.
Если вы загружаете изображения с внешнего сайта, и внешний сайт устанавливает HTTP-заголовок Content-Length
, вы можете оценить, поместится ли изображение в память еще до того, как начнете загружать поток...