1

我已经到了通过调试和跟踪对象很难得到答案的地步,所以我需要一些帮助。

我正在尝试做的事情: 我的屏幕捕捉宠物项目的历史表格。历史记录必须将所有图像列为缩略图(例如:picasa)。

我做了什么: 我创建了一个 HistoryItem:UserControl。这个历史项目有几个按钮、一个复选框、一个标签和一个图片框。这些按钮用于删除/编辑/复制图像。复选框用于选择一个或多个图像,标签用于一些信息文本。图片框从作为路径的公共属性获取图像,并且一个方法创建一个比例缩略图以在加载控件时显示它。此用户控件有两个公共事件。一种用于删除图像,另一种用于使鼠标进入和鼠标离开所有控件的事件冒泡。为此,我使用EventBroadcastProvider。冒泡很有用,因为无论我将鼠标移到控件上的哪个位置,按钮都会出现。dispose 方法已扩展,我手动删除了事件。

通过循环包含所有图像路径的 xml 文件来加载所有图像。对于此 XML 中的每个图像,我创建了一个新的 HitoryItem,它被添加到流布局面板中(经过一些编码以排序和限制加载的图像数量)。

问题: 当我在历史表单中午餐时,流布局面板中填充了我的 HistoryItem 自定义控件,我的内存使用量急剧增加。从 14Mb 到大约 100MB,加载了 100 张图像。通过关闭历史表单并处理我可以处理的任何内容,甚至尝试调用 GC.Collect() 内存增加仍然存在。我搜索任何无法像图像或事件一样正确处置的对象,但无论我在哪里使用它们,它们都会被处置。问题接缝来自多个来源。一是冒泡的事件没有正确处理,二是来自图片框本身。当仅加载没有任何图像处理甚至事件的自定义控件时,我可以通过将所有代码注释为有限版本来看到所有这些。如果没有这些事件,内存消耗就会减少 20%。


所以我真正的问题是,如果这种逻辑、流布局面板和带有图片框的自定义控件,是否是将大量图像显示为缩略图的最佳解决方案。

谢谢!

4

1 回答 1

1

我曾经这样做过,但在内存管理方面很糟糕。例如,您冒着越来越多的 GDI 句柄的风险(例如,如果每个控件都创建 Font 或其他 GDI 对象实例),而这个问题不能用 GC.Collect() 解决。

我在 ComponentOwl.com 工作,我们开发了一个用于管理图像缩略图的控件,称为Better Thumbnail Browser,它还可以为您加载、调整大小和缓存缩略图:

更好的缩略图浏览器概述

他们还有一个名为Better ListView Express的免费组件,它仍然对图像缩略图有很好的支持。

于 2012-12-01T20:29:23.410 回答