I got to a point where it's very difficult to get answers by debugging and tracing objects, so i need some help.
What I'm trying to do: A history form for my screen capture pet project. The history must list all images as thumbnails (ex: picasa).
What I've done: I created a HistoryItem:UserControl. This history item has a few buttons, a check box, a label and a picture box. The buttons are for delete/edit/copy image. The check box is used for selecting one or more images and the label is for some info text. The picture box is getting the image from a public property that is a path and a method creates a proportional thumbnail to display it when the control has been loaded. This user control has two public events. One for deleting the image and one for bubbling the events for mouse enter and mouse leave trough all controls. For this I use EventBroadcastProvider. The bubbling is useful because wherever I move the mouse over the control, the buttons appear. The dispose method has been extended and I manually remove the events.
All images are loaded by looping a xml file that contains the path of all images. For each image in this XML I create a new HitoryItem that is added (after a little coding to sort and limit the amount of images loaded) to a flow layout panel.
The problem: When I lunch the history form, and the flow layout panel is populated with my HistoryItem custom control, my memory usage increases drastically.From 14Mb to around 100MB with 100 images loaded. By closing the history form and disposing whatever I could dispose and even trying to call GC.Collect() the memory increase remain. I search for any object that could not be disposed properly like an image or event but wherever I used them they are disposed. The problem seams to be from multiple sources. One is that the events for bubbling are not disposing properly, and the other is from the picture box itself. All of this i could see by commenting all the code to a limited version when only the custom control without any image processing and even events is loaded. Without the events the memory consumption is reduced by axiomatically 20%.
So my real question is if this logic, flow layout panels and custom controls with picture boxes, is the best solution for displaying large amounts of images as thumbnails.
Thank you!
I have once done exactly this and it is terrible when it comes to memory management. For example, you are risking growing number GDI handles (e.g. if every control creates Font or other GDI object instance) and this problem cannot be solved with GC.Collect().
I work for ComponentOwl.com and we have developed a control for managing image thumbnails called Better Thumbnail Browser which can do also loading, resizing and caching thumbnails for you:
They have also a free component called Better ListView Express, which still have great support for image thumbnails.