0

I'm writing a program that open a folderBrowserDialog1 and then loop through the files in a directory using

using string[] files = Directory.GetFiles(folderBrowserDialog1.SelectedPath, "*.*", SearchOption.AllDirectories);

to get all the files in the folder and the sub folders, later on the program split the array of strings into multiple lists, that filters the data to 4 types

public static readonly List<string> ImageExtensions = new List<string> { ".JPG", ".JPE", ".BMP", ".GIF", ".PNG" };
public static readonly List<string> OfficeExtensions = new List<string> { ".DOC", ".DOCX", ".XLS", ".XLSX", ".PPT",".PPTX",".XLM",".PPS",".PPSX",".MDB" };
public static readonly List<string> VideoExtensions = new List<string> { ".FLV", ".AVI", ".MOV", ".MP4", ".MPG", ".WMV", ".3GP", ".ASF", ".RM", ".SWF",".MTS" };
public static readonly List<string> AudioExtensions = new List<string> { ".AAC", ".MP3", ".OGG", ".WMA", ".WAV" };

public static List<string> images = new List<string>();
public static List<string> audio = new List<string>();
public static List<string> videos = new List<string>();

I'm taking the pictures to display them in thumbs in another form code is the following:

public partial class frm_brsimag : MainForm
{
    public static List<string> selimages = new List<string>();
    int currPos = 0;
    const int pageCount = 100;
    public frm_brsimag()
    {
        InitializeComponent();
    }

    private void frm_brsimag_Load(object sender, EventArgs e)
    {
        menuStrip1.Hide();
    }

    private void LoadImages(int startFrom, int to)
    {
        flowLayoutPanel1.Controls.Clear();
        for (int file = startFrom; file < startFrom + to; file++)
        {
            LinkLabel l = new LinkLabel();
            l.Tag = FileManager.images[file];
            l.Text = Path.GetFileNameWithoutExtension(FileManager.images[file]);
            flowLayoutPanel1.FlowDirection = FlowDirection.TopDown;
            PictureBox picBox = new PictureBox();
            picBox.SizeMode = PictureBoxSizeMode.StretchImage;
            picBox.ContextMenuStrip = contextMenuStrip1;
            picBox.Height = 125;
            picBox.Width = 125;
            picBox.LoadAsync(FileManager.images[file]);
            //Label lbl = new Label();
            // lbl.Text = Path.GetFileNameWithoutExtension(FileManager.images[file]);
            flowLayoutPanel1.Controls.Add(picBox);
            flowLayoutPanel1.Controls.Add(l);
            l.LinkClicked += new LinkLabelLinkClickedEventHandler(LinkedLabelClicked);
            //flowLayoutPanel1.Controls.Add(lbl);
        }
    }
    private void LinkedLabelClicked(object sender, LinkLabelLinkClickedEventArgs e)
    {
        string filepath = ((LinkLabel)sender).Tag.ToString();
        Process.Start("explorer.exe", "/select," + filepath);
    }

    private void btnNext_Click(object sender, EventArgs e)
    {
        if (FileManager.images.Count - currPos > pageCount)
        {
            LoadImages(currPos, pageCount);
            currPos += pageCount;
        }
        else
        {
            LoadImages(currPos, FileManager.images.Count - currPos);
            currPos += FileManager.images.Count - currPos;
        }
    }

    private void btnPrev_Click(object sender, EventArgs e)
    {
        if (currPos >= pageCount)
            currPos -= pageCount;
        else
            currPos = 0;
        LoadImages(currPos, pageCount);
    }

The problem is: I have a big number of files do deal with like 35K of pics sometimes.

I tried to make a next and previous button that load the pictures 100 by 100 in the form as the picture shows, to prevent the app from consuming a lot of space from memory, but its not working, when I load the program with the pictures task manager showed that the program consumed 1.2 GB, and when I press the next button, it keeps on increasing can you help out, and after many page navigation the program crashed, thanks! design of the forum so i makes things clear: https://i.stack.imgur.com/gdOYO.jpg

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Z. Kiwan
  • 123
  • 1
  • 14
  • Your making a lot of pictureboxes so im not surprised with the memory usage, have you thought about updating these pictureboxes with the next 100 images? (next/previous button to cycle through) – Sayse Mar 28 '14 at 14:39
  • Are you releasing the memory used to hold your thumbnail images as you scroll? I see a lot of creation of pictureboxes and adding them to the form, but no removal or updating. Every page just adds more and more. – selkathguy Mar 28 '14 at 14:41
  • sorry i don't understand exactly what you mean by updating the pictureboxes with the next 100 images? – Z. Kiwan Mar 28 '14 at 14:42
  • `pictureBox.Image = nextImage`. Of course you'll still need to dispose of the old image, Its not clear what layout your pictureboxes are in – Sayse Mar 28 '14 at 14:43
  • i added a picture to show you http://i.stack.imgur.com/gdOYO.jpg its here – Z. Kiwan Mar 28 '14 at 14:44

1 Answers1

0

Never mind, my previous answer didn't notice that you did clear flowLayoutPanel1. That said, you clear its contents without removing handler, nor disposing disposable objects (which controls are) - that's at least part of your problem as having that event handler attached keeps the source instance in memory.

So before clearing controls, detach handler like so (code added without testing - may need adjustments). See if this helps with your memory issue.

private void LoadImages(int startFrom, int to)
{
    foreach(var control in flowLayoutPanel1.Controls)
    {
        if(control is LinkLabel)
        {
            // Detach handlers
            (control as LinkLabel).LinkClicked -= new LinkLabelLinkClickedEventHandler(LinkedLabelClicked);
        }

        // Dispose of controls we're about to clear out...
        control.Dispose();
    }

    flowLayoutPanel1.Controls.Clear();

    for (int file = startFrom; file < startFrom + to; file++)
    {
        LinkLabel l = new LinkLabel();
        l.Tag = FileManager.images[file];
        l.Text = Path.GetFileNameWithoutExtension(FileManager.images[file]);
        flowLayoutPanel1.FlowDirection = FlowDirection.TopDown;
        PictureBox picBox = new PictureBox();
        picBox.SizeMode = PictureBoxSizeMode.StretchImage;
        picBox.ContextMenuStrip = contextMenuStrip1;
        picBox.Height = 125;
        picBox.Width = 125;
        picBox.LoadAsync(FileManager.images[file]);
        //Label lbl = new Label();
        // lbl.Text = Path.GetFileNameWithoutExtension(FileManager.images[file]);
        flowLayoutPanel1.Controls.Add(picBox);
        flowLayoutPanel1.Controls.Add(l);
        l.LinkClicked += new LinkLabelLinkClickedEventHandler(LinkedLabelClicked);
        //flowLayoutPanel1.Controls.Add(lbl);
    }
}
LB2
  • 4,802
  • 19
  • 35
  • sorry but I'm not professional with c#, what I'm supposed to do to free up the memory each time i press the next button ? – Z. Kiwan Mar 28 '14 at 14:43
  • @user2597549 You need to decide at which point you no longer need your images loaded into the `flowLayoutPanel1`, and remove from there (including removing the event handler). This way you'll reclaim memory by removing images (and related controls) that are no longer needed to be loaded. As to when to do it, depends on requirements for your app. – LB2 Mar 28 '14 at 14:48
  • lets say i want to free the memory up each next click or previous click what i'm supposed to do ? – Z. Kiwan Mar 28 '14 at 14:49
  • @user2597549 My initial assessment was partially wrong. You do clear out from container, BUT not releasing handler, and not disposing. See if the code above helps... – LB2 Mar 28 '14 at 15:15
  • And why do you keep full size images in this? Never heard of thumbnails? An image may take 20+mb memory like that - a thumbnail would use a LOT less memory. A LOT LESS. – TomTom Mar 28 '14 at 15:17
  • Hello Sorry for the late reply but i have just reached work, `control.Dispose();` is giving me an error object does not contain the definition of dispose ? – Z. Kiwan Mar 31 '14 at 05:15
  • @TomTom Thumbs makes problems as they don't load sometime i want a clear result. – Z. Kiwan Mar 31 '14 at 05:16
  • @user2597549 Ok. so you want to load hundreds of full size images but not spend the memory? Any other illogical wishes? Thumbnails will load all the time when you are acapable of writing the code correctly and they will use a LOT less memor than possibly multi megabyte full size images. There is no way not to have thumbnails AND optimize memory consumption. – TomTom Mar 31 '14 at 05:54
  • if you load small amount of images everytime it wont eat up the memory :), and i have no experience with thumbs :/, if you can reform this code to load thumbs with link labels etc i will be thankfull to you :) :) – Z. Kiwan Mar 31 '14 at 06:14
  • @user2597549 Can you paste the exact error message you get (and value of `control` when it happens? Also, see [this SO post](http://stackoverflow.com/a/2001692/1556108) on resizing the image and preserving aspect ratio (to create thumbnails). – LB2 Mar 31 '14 at 13:37