.NET ImageList实现中的ImageList容量错误?

时间:2012-04-16 20:10:27

标签: .net image imagelist

我在.net应用程序中为ListView使用ImageList时遇到了一些问题。在我的实现中,这个ImageList可以根据用途保存几千个图像。这个问题最初是在我尝试使用大量图像时出现的。一旦我越过5K +图像,我就会遇到一个通用的“图像无法添加到ImageList”异常,试图添加图像。这次失败发生的确切数字跳了一下。

因此,在尝试解决此问题时,我尝试使用本机ImageList_SetImageCount函数扩展ImageList的容量。那很好,解决了我的直接问题。我不得不使用ImageList [index] = image而不是.Add()方法填充列表。 这一切都很好,但是当把图像拉出来的时候,问题就出现了。现在,无论何时我通过索引在ImageList中引用一个图像,我都会得到一个Out of Memory Exception。位图x = ImageList [任何索引]都会崩溃。

我尝试过追逐这么多不同的方法,但仍然遇到了ImageList的问题。

在我最后一次尝试进一步探讨这个问题时,我把下面的一段测试代码放在一起,它仍然表现得很奇怪!

    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");

最后一行因“无法将图像添加到ImageList”错误而崩溃。奇怪的是,将第二个循环设置为较低的迭代(即200个,总共添加了2000个图像),它表现得很好。

.net中的ImageList是否有一定的阈值我不知道?任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

我发布的代码无法获得任何回复。然而,重要的是要意识到ImageList会生成位图的副本。所以你应该在添加后调用位图的Dispose()方法。如果不这样做,则存在严重的风险,即当垃圾收集器不能经常运行以便在您之后清理时,您将耗尽由位图数据消耗的非托管内存并且致命。这不适用于代码段,因为只有10个位图。

答案 1 :(得分:0)

当您使用Reflector查看最后一行代码的作用时,您会看到,ImageList的setter实际上在这一行上失败了:

bool flag2 = SafeNativeMethods.ImageList_Replace(new HandleRef(this.owner, this.owner.Handle), index, new HandleRef(null, handle), new HandleRef(null, monochromeMask));

它涉及使用Windows限制的句柄(如果我没记错的话,每个进程10000个)。因此,虽然你有很多可用内存,但你可能已达到句柄限制。