问题
I am having some problems utilizing an ImageList for my ListView in a .net application. In my implementation, this ImageList can hold a few thousand images depending on use. The issue originally arose when I was trying to work with a large number of images. Once I was getting past 5K+ images, I was running into a generic "Image cannot be added to the ImageList" exception trying to add an image. The exact number where this failure occurred jumped around a little bit.
So, in trying to solve this issue I've tried to expand the capacity of the ImageList using native ImageList_SetImageCount function. That was fine and solved my immediate problem. I had to populate the list using the ImageList[index] = image instead of the .Add() method. This was all fine but when it came time to pulling an image out, the problems crept in. Now, anytime I reference an image in that ImageList by index I get an Out of Memory Exception. Bitmap x = ImageList[any index] would crash.
I've tried chasing this many different ways and am still encountering issues with the ImageList.
In my last attempt to explore the issue further, I put together the following piece of test code which is still behaving odd!
private void Form1_Load(object sender, EventArgs e)
{
list = new ImageList();
list.ImageSize = new Size(128, 128);
list.ColorDepth = ColorDepth.Depth32Bit;
Image[] images = new Image[10];
for (int y = 0; y < 10; y++)
{
images[y] = new Bitmap(@"Path to loading_photo.png");
}
for (int x = 0; x < 750; x++)
{
list.Images.AddRange(images);
}
list.Images[12] = new Bitmap(@"Path to another.png");
the last line crashes with "Image cannot be added to the ImageList" error. Oddly, setting the second loop to lower iteration (i.e. 200 for a total of 2000 images being added) it behaves just fine.
Is there a certain threshold on ImageList in .net I am not aware of? Any help would be greatly appreciated.
回答1:
I can get no repro whatsoever with the posted code. It is however important to realize that ImageList makes a copy of the bitmap. So you should call the bitmap's Dispose() method after adding it. If you don't then there's a serious risk that you'll run out of unmanaged memory, consumed by the bitmap data and fatal when the garbage collector doesn't run often enough to clean up after you. This doesn't apply to the snippet since there are only 10 bitmaps.
回答2:
When you use Reflector to look what your last line of code does, you'll see, that setter of ImageList is actually failing on this line:
bool flag2 = SafeNativeMethods.ImageList_Replace(new HandleRef(this.owner, this.owner.Handle), index, new HandleRef(null, handle), new HandleRef(null, monochromeMask));
It involves working with handles, which are in Windows limited (10000 per process if I recall correctly). So although you have a lot of free memory, you have probably reached limit of handles.
来源:https://stackoverflow.com/questions/10180954/imagelist-capacity-bug-in-net-imagelist-implementation