0

I have a very simple code in a VB.NET program to load all paths in a folder in a text box. The code works great, the problem is that it adds the lines in real time, so it takes about 3 minutes to load 20k files while the interface is displaying line by line.

This is my code:

    Dim ImageryDB As String() = IO.Directory.GetFiles("c:\myimages\")

    For Each image In ImageryDB
        txtbAllimg.AppendText(image & vbCrLf)
    Next

How can I force my program to load the files in chunks or update the interface every second?

Thanks in advance

daviddgz
  • 25
  • 1
  • 8
  • This is an entirely self-inflicted problem. There's not a user in the world that thinks that textbox is useful. Nobody likes look at a crazily scrolling window, having to read 20,000 lines of text or would ever consider editing it. So just get rid of the textbox. Use a Label instead, updating it once every 100 msec is plenty good enough. Use [this one](http://stackoverflow.com/a/2397968/17034). – Hans Passant Sep 14 '15 at 13:06
  • A listbox is not an option in this case because of other tools using with this app. This is not intended for the people to read 20000 lines but to process them afterwards... – daviddgz Sep 14 '15 at 15:36
  • Label, not ListBox. Use a StringBuilder to "process them afterwards". – Hans Passant Sep 14 '15 at 15:45

2 Answers2

0

Yes, you can do that. You'll need to load the file names into an off-screen data structure of some kind rather than loading them directly into the control. Then you can periodically update the control to display whatever is loaded so far. However, I think you'll find that the slowness comes only from updating the control. Once you remove that part, there will be no need to update the control periodically during the loading process since it will be nearly instantaneous.

You could just load all of the file names into a string and then only set the text box to that string after it's been fully loaded, like this:

Dim imagePaths As String = ""
For Each image As String In Directory.GetFiles("c:\myimages\")
    imagePaths &= image & Environment.NewLine
Next
txtbAllimg.Text = imagePaths

However, that's not as efficient as using the StringBuilder:

Dim imagePaths As New StringBuilder()
For Each image As String In Directory.GetFiles("c:\myimages\")
    imagePaths.AppendLine(image)
Next
txtbAllimg.Text = imagePaths.ToString()

However, since the GetFiles method is already returning the complete list of paths to you as a string array, it would be even more convenient (and likely even more efficient) to just use the String.Join method to combine all of the items in the array into a single string:

txtbAllimg.Text = String.Join(Environment.NewLine, Directory.GetFiles("c:\myimages\"))
Steven Doggart
  • 43,358
  • 8
  • 68
  • 105
  • Thank you very much Steve for help! First option took 14 seconds, second and third only 3 to load 20k paths in the txtbox! This is exactly what I was looking for, you are a master! I am taking good account of the codes and taking into consideration for the future, I didn't know about Stringbuilder. – daviddgz Sep 14 '15 at 16:35
0

I know that this is not an answer to your actual question, but AppendText is slow. Using a ListBox and Adding the items to it is approx. 3 times faster. The ListBox also has the benefit of being able to select an item easily (at least more easily than a TextBox)

For each image in ImageryDB
     Me.ListBox1.Items.add (image)
Next

However, there is probably an even more useful and faster way to do this. Using FileInfo.

Dim dir As New IO.DirectoryInfo("C:\myImages")
Dim fileInfoArray As IO.FileInfo() = dir.GetFiles()
Dim fileInfo As IO.FileInfo

For Each fileInfo In fileInfoArray
    Me.ListBox2.Items.Add(fileInfo.Name)
Next
APrough
  • 2,671
  • 3
  • 23
  • 31