下面是一个如何从字节数组加载图像的示例,已知字节数组具有有效的图像数据(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作为页面上Image元素的源,但错误发生在上面的img.SetSource(…)行中.
将GC.Collect()添加到我正在加载缩略图图像的循环中让我加载了更多图像,所以我认为这与内存管理有关但我不知道我能做些什么来解决问题.
解决方法
When Silverlight loads an image,the framework keeps a reference and caches the decoded image until flow control is returned to the UI thread dispatcher. When you load images in a tight loop like that,even though your application doesn’t retain a reference,the GC can’t free the image until we release our reference when flow control is returned.
After processing 20 or so images,you could stop and queue the next set using Dispatcher.BeginInvoke just to break up the work that is processed in one batch. This will allow us to free images that aren’t retained by your application.
I understand with the current decode behavior it’s not obvIoUs that Silverlight is retaining these references,but changing the decoder design could impact other areas,so for now I recommend processing images like this in batches.
Now,if you’re actually trying to load 500 images and retain them,you are still likely to run out of memory depending on image size. If you’re dealing with a multi-page document,you may want to instead load pages on demand in the background and release them when out of view with a few pages of buffer so that at no point do you exceed reasonable texture memory limits.