Solved

Taking too long to populate 4,000+ filenames in a ListView object in C#.

Posted on 2008-10-21
5
605 Views
Last Modified: 2013-12-17
I have a LIstView object on my Windows Form that for starters, I want to list around 4,500 + filenames from a remote server. Problem is, its taking around 12 minutes to populate the LV Control.
I've attached my code below. Can anyone show me how to write the code what would allow this app to increase that time using Multithreading/ a delegate? I would at least like to see the filenames be listed and possibly a number count being performed on the files via a Label as well.
Many thanks EE Guru's,
Wally
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
 
namespace ParseLogErrors
{
    public partial class Form1 : Form
    {
        private System.Collections.Specialized.StringCollection folderCol;
       
        public Form1()
        {
            InitializeComponent();
 
            // Init ListView and folder collection
            folderCol = new System.Collections.Specialized.StringCollection();
            CreateHeadersAndFillListView();
            PaintListView(@"\\crprdnsrc03\logs$\sd4\regional");
            folderCol.Add(@"\\crprdnsrc03\logs$\sd4\regional");
            
            //this.lvwFilesAndFolders.ItemActivate += System.EventHandler(this.lvwFilesAndFolders_ItemActivate);
        }
 
        private void buttonParseLogs_Click(object sender, EventArgs e)
        {
            string dirName = textBoxSearchPath.Text;
            //DirectoryInfo dir1 = new DirectoryInfo("\\" + dirName);
            
            // Set current working directory & verify it exists
            if (Directory.Exists(dirName))
            try
            {
                Directory.SetCurrentDirectory(dirName);
                MessageBox.Show(dirName);
            }
            catch (UnauthorizedAccessException)
            {
                MessageBox.Show("Not authorized to access " + dirName);
                return;
            }
            catch (FileNotFoundException)
            {
                MessageBox.Show("No such directory: " + dirName);
                return;
            }    
        }
 
        private void CreateHeadersAndFillListView()
        {
            ColumnHeader colHead;
 
            colHead = new ColumnHeader();
            colHead.Width = 500;
            colHead.Text = "Filename";
            this.lvwFilesAndFolders.GridLines = true;
            this.lvwFilesAndFolders.Columns.Add(colHead);
 
            colHead = new ColumnHeader();
            colHead.Width = 100;
            colHead.Text = "Size";
            this.lvwFilesAndFolders.GridLines = true;
            this.lvwFilesAndFolders.Columns.Add(colHead);
 
            colHead = new ColumnHeader();
            colHead.Width = 200;
            colHead.Text = "Last Accessed";
            this.lvwFilesAndFolders.GridLines = true;
            this.lvwFilesAndFolders.Columns.Add(colHead);
        }
 
        private void PaintListView(string root)
        {
            try
            {
                ListViewItem lvi;
                ListViewItem.ListViewSubItem lvsi;
 
                this.labelDisplayLogInfo.Text = root + "    (Double click to display the path name)";
                DirectoryInfo dir = new DirectoryInfo(root);
 
                this.lvwFilesAndFolders.Items.Clear();
 
                DirectoryInfo[] dirs = dir.GetDirectories();
                FileInfo[] files = dir.GetFiles();
 
                this.lvwFilesAndFolders.BeginUpdate();
 
                foreach (System.IO.FileInfo fi in files)
                {
                    lvi = new ListViewItem();
                    lvi.Text = fi.Name;
                    lvi.Tag = fi.FullName;
 
                    lvsi = new ListViewItem.ListViewSubItem();
                    lvsi.Text = formatsizekb(fi.Length);
                    lvi.SubItems.Add(lvsi);
 
                    lvsi = new ListViewItem.ListViewSubItem();
                    lvsi.Text = fi.LastAccessTime.ToString();
                    lvi.SubItems.Add(lvsi);
 
                    this.lvwFilesAndFolders.Items.Add(lvi);
                }
 
                this.lvwFilesAndFolders.EndUpdate();
            }
            catch (System.Exception err)
            {
                MessageBox.Show("Error: " + err.Message);
            }
 
            this.lvwFilesAndFolders.View = View.Details;
        }
 
        private void lvwFilesAndFolders_ItemActive(object sender, System.EventArgs e)
        {
            ListView lvw = (ListView)sender;
            string filename = lvw.SelectedItems[0].Tag.ToString();
            Console.WriteLine(filename);
        }
 
        private void buttonExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }
 
        private string formatsizekb(long lsize)
        {
            const int iKB = 1024;
            const long lMB = 1048576;
 
            if (lsize < iKB)
                return string.Format("{0:#,#} bytes", lsize);
            else if (lsize >= iKB && lsize < lMB) ;
            return string.Format("{0:#,#} KB", lsize / 1024);
        }
    }
}

Open in new window

0
Comment
Question by:wally_davis
  • 3
  • 2
5 Comments
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 22772012
It might help if you included some of the relevant code like *how* you are adding them to the listview.

Is the time in getting the list of files or in actually adding them to the listbox? I would guess the former. If so it would seem that you would want to get the filenames on a background thread then add them to the listbox as you get them but without more details its really hard to give you direction.

Cheers,

Greg
0
 

Author Comment

by:wally_davis
ID: 22776818
Hi Greg,
If you look under the "private void PaintListView(string root)" subroutine, you'll notice under the foreach loop routine, this is where the files get added to the ListView control, i.e. the "  this.lvwFilesAndFolders.Items.Add(lvi);" Method. It took approximately 12 - 15 minutes to populate 4,500 filenames to the ListView control (named lvwFilesAndFolders).

foreach (System.IO.FileInfo fi in files)
                {
                    lvi = new ListViewItem();
                    lvi.Text = fi.Name;
                    lvi.Tag = fi.FullName;
 
                    lvsi = new ListViewItem.ListViewSubItem();
                    lvsi.Text = formatsizekb(fi.Length);
                    lvi.SubItems.Add(lvsi);
 
                    lvsi = new ListViewItem.ListViewSubItem();
                    lvsi.Text = fi.LastAccessTime.ToString();
                    lvi.SubItems.Add(lvsi);
 
                    this.lvwFilesAndFolders.Items.Add(lvi);
                }
0
 

Author Comment

by:wally_davis
ID: 22777017
For starters, I don't mind using the BackgroundWorker control and then later Delegates. But either one will work.
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 22778692
Ah sorry my bad I missed the scroll bar ... give me a few minutes to look it over.
0
 

Accepted Solution

by:
wally_davis earned 0 total points
ID: 22791319
Figured out the code I needed to get this to start working. This is not complete but it's a good start.

 protected void bgw_DoWork(object sender, DoWorkEventArgs e)
        {            
            {
                this.Invoke(new MethodInvoker(delegate()
                {
                    progressBar1.PerformStep();

                    /* Lets call the other statements from here
                    to Perform Safe threading execution */
                    string dirName = textBoxSearchPath.Text;
                    folderCol = new System.Collections.Specialized.StringCollection();
                    PaintListView(dirName);
                    folderCol.Add(dirName);
                }));                                
            }                        
        }
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Welcome my friends to the second instalment and follow-up to our Minify and Concatenate Your Scripts and Stylesheets (http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/A_4334-Minify-and-Concatenate-Your-Scripts-and-Stylesheets.html)…
A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

773 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question