2011-07-08 24 views
7

我需要動態加載許多(有時是數百)的縮略圖圖像。出於性能方面的原因,我需要在有限的請求中執行此操作,我正在使用單個請求/響應進行測試。我在響應中發送圖像的二進制數據,並使用MemoryStream將它們加載到BitmapImage中。這工作正常,直到我加載超過80個縮略圖,然後我得到災難性的失敗例外。爲了確保我的數據沒有損壞,我嘗試了多次使用相同的字節數組加載BitmapImage,並且在加載80次後崩潰。Silverlight的:從流的BitmapImage(從HRESULT災難性故障(異常:0x8000FFFF(E_UNEXPECTED)))拋出異常

下面是如何將圖像從字節數組加載的樣品,字節陣列已知具有有效的圖像數據(PNG):

private BitmapImage LoadImage(byte[] imageData) 
{ 
    BitmapImage img = new BitmapImage(); 
    MemoryStream stream = new MemoryStream(imageData); 
    img.SetSource(stream); // Exception thrown here after too many images loaded. 
    return img; 
} 

我然後使用BitmapImage的作爲用於源極頁面上的圖像元素,但錯誤發生在上面的img.SetSource(...)行中。

GC.Collect()添加到我加載縮略圖圖像的循環中讓我加載更多圖像,所以我認爲這與內存管理有關,但我不知道我能做些什麼來解決問題。

+0

,我不知道這可能是問題,但MemoryStream的確實有ReadTimeout和WriteTimeout性能。該流是否會超時? – Danexxtone

+0

我嘗試設置ReadTimeout並得到一個異常:此流不支持超時。 – toby

+0

你能澄清一些事情:爲什麼一個字節數組?是否沒有可以直接下載到「img.SetSource」的下載流?你確定下載的PNG是「縮略圖」大小還是下載由圖像控件縮放的大圖像?這些照片的縮略圖是? – AnthonyWJones

回答

6

我想引用答案微軟在上面的錯誤報告提供值得,因爲它是非常簡潔的描述性的問題,以及提供建議的解決方案:

在Silverlight中加載圖像時,框架保留一個引用並緩存解碼後的圖像,直到流控制返回給UI線程調度器。當您像這樣的緊密循環加載圖像時,即使應用程序沒有保留引用,GC仍然無法釋放圖像,直到我們在返回流控制時發佈引用。

處理20張左右的圖像後,你可以停下來排隊使用Dispatcher.BeginInvoke剛分手是在一個批處理工作的下一組。這將允許我們釋放未被應用程序保留的圖像。

我與當前解碼的行爲理解它並不明顯,Silverlight是保留這些引用,但改變解碼器的設計可能會影響其他地區,所以現在我建議處理相似圖片批量。

現在,如果您實際上是試圖加載500張圖片,並留住他們,你仍可能用完取決於圖像大小的內存。如果您正在處理多頁文檔,則可能需要在後臺按需加載頁面,並在不帶視圖的情況下使用幾頁緩衝區釋放它們,以便在任何時候都不會超出合理的紋理內存限制。