문제

시스템 : Windows XP SP3, .NET 3.5, 4GB RAM, 듀얼 1.6GHz

스토리 보드 애니메이션 사용 (사용)을로드 및 전환하는 WPF 응용 프로그램이 매우 큰 PNG가 있습니다. 이 PNG는 해상도에서 8190x1080입니다. 응용 프로그램이 실행되면 이미지를 캐시하고 시스템 메모리가 천천히 올라갑니다. 결국 그것은 시스템을 질식시키고 OutofMemoryException을 던진다.

다음은 이것을 해결하기 위해 현재 취하는 단계입니다.

1) 앱에서 BitMapSource 객체를 제거하고 있습니다.

2) BitMapSource를로드 할 때 BitMapSource BitMapCacheOption을 NONE로 설정하고 있습니다.

3) BitMapsource가로드되면 동결됩니다.

4) 소스를 사용하는 이미지에 대한 모든 참조와 소스 자체에 대한 참조를 삭제하고 있습니다.

5) 위의 단계가 완료된 후 수동으로 gc.collect ()를 호출합니다.

WPF가 왜 이러한 이미지에 대한 메모리에 매달려 있는지 알아 내고로드하는 데 사용 된 메모리가 올바르게 복구되도록 할 수있는 솔루션을 알아 내기를 희망합니다.

도움이 되었습니까?

해결책

당신은 확실히 이것에 대해 많은 작업을했습니다. 주요 문제는 BitMapCacheOption이라는 것입니다.

GC.Collect ()를 수행하고 300 개의 다른 URI에서 300 개의 작은 이미지를로드하고 GC.Collect ()를 다시 호출하는 등 몇 가지 까다로운 솔루션이 있지만 간단한 것은 간단합니다.

URI에서로드하는 대신 스트림을 구성하여 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 ()에서 하중이 발생하게됩니다. 우리의 경우 캐싱은 불가능하므로 부하가 즉시 발생하게됩니다.

분명히이 코드를 UI 스레드에서 실행하고 BitMapsource를 동결하여 이동할 수 있도록 원할 것입니다.

내가 왜 내가 bitmapcreateoptions.ignoreimagecache를 사용하지 않았는지 궁금 할 것입니다. 캐싱이 URI가없는 경우가 불가능하다는 사실 외에, INGOREIMAGECACHE는 이미지 캐시를 완전히 무시하지 않습니다. 따라서 INGOREIMAGECACHE가 설정 되더라도로드 된 이미지는 여전히 캐시에 삽입됩니다. 차이점은 캐시의 기존 이미지가 무시된다는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top