Как Вы удостоверяетесь, что WPF выпускает крупный BitmapSource из памяти?

Можно хотеть попробовать наш инструмент, BitRock InstallBuilder. Хотя это - исходное приложение, много наших клиентов использует его для упаковки настольных JAVA-приложений. Если Вы связываете JRE и создаете средство запуска, и т.д. пользователь даже не должен знать, что они устанавливают JAVA-приложение. Это является кросс-платформенным, таким образом, можно генерировать установщики и для Windows и для Mac (и Linux, Солярис, и т.д.) Как install4j инструмент, упомянутый в другом сообщении, это - коммерческий инструмент, , но мы имеем бесплатные лицензии на проекты с открытым исходным кодом и специальные скидки для microISVs / малый бизнес, и т.д. просто отбрасываем нас электронное письмо. Также требуемый, чтобы подчеркнуть, что это - инструмент установщика, таким образом, он не обратится к Вашим потребностям, если Вы будете только искать единственный исполняемый файл файла.

14
задан discorax 5 November 2009 в 23:52
поделиться

1 ответ

Вы, безусловно, много поработали над этим. Я думаю, что основная проблема заключается в том, что BitmapCacheOption.None не предотвращает кэширование базовых BitmapDecoder (ов).

Есть несколько сложных решений, таких как выполнение GC.Collect (), загрузка 300 маленьких изображений из 300 другой Uris и вызов GC.Collect () снова, но простой вариант прост:

Вместо загрузки из Uri просто создайте Stream и передайте его конструктору BitmapFrame:

var source = new BitmapImage();
using(Stream stream = ...)
{
  source.BeginInit();
  source.StreamSource = stream;
  source.CacheOption = BitmapCacheOption.OnLoad;    // not a mistake - see below
  source.EndInit();
}

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

Почему BitmapCacheOption.OnLoad? Это кажется нелогичным, но этот флаг имеет два эффекта: он включает кеширование, если кеширование возможно, и это вызывает загрузку в EndInit (). В нашем случае кэширование невозможно, поэтому все, что оно делает, вызывает немедленную загрузку.

Очевидно, вы захотите запустить этот код из потока пользовательского интерфейса, а затем заморозить BitmapSource, чтобы вы могли его переместить.

Вы также можете спросить, почему я не использовал BitmapCreateOptions.IgnoreImageCache. Помимо того факта, что кэширование невозможно без указания URI, IgnoreImageCache не полностью игнорирует кеш изображения: он игнорирует его только для чтения. Таким образом, даже если установлен IgnoreImageCache, загруженное изображение все равно будет вставлено в кеш. Разница в том, что существующее изображение в кэше игнорируется.

затем заморозьте BitmapSource, чтобы его можно было переместить.

Вы также можете задаться вопросом, почему я не использовал BitmapCreateOptions.IgnoreImageCache. Помимо того факта, что кеширование невозможно без указания URI, IgnoreImageCache не полностью игнорирует кеш изображения: он игнорирует его только для чтения. Таким образом, даже если установлен IgnoreImageCache, загруженное изображение все равно будет вставлено в кеш. Разница в том, что существующее изображение в кэше игнорируется.

затем заморозьте BitmapSource, чтобы его можно было переместить.

Вы также можете задаться вопросом, почему я не использовал BitmapCreateOptions.IgnoreImageCache. Помимо того факта, что кэширование невозможно без указания URI, IgnoreImageCache не полностью игнорирует кеш изображения: он игнорирует его только для чтения. Таким образом, даже если установлен IgnoreImageCache, загруженное изображение все равно будет вставлено в кеш. Разница в том, что существующее изображение в кэше игнорируется.

загруженное изображение все еще вставлено в кеш. Разница в том, что существующее изображение в кэше игнорируется.

загруженное изображение все еще вставлено в кеш. Разница в том, что существующее изображение в кэше игнорируется.

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

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