문제

I am rather new to VB and I am trying to figure out how I can do a certain routine. I am writing an archive program that has a checklistbox populated with all the directories on a certain drive. As the user checks on of the directories, it goes into a for loop that grabs the directory size and shows it on the form. But the issue that I am having is that once you start choosing more than 4 or 5 it gets slower and slower since it is reading through all the checkeditems and validating file size with. Is there a method for me to just grab last item checked or unchecked so i can just add/subtract from the current size? This my current code looping through all the checked items. Thank you in advance.

Dim fsize As Long = 0
Private Sub chklstbxWorkspace_SelectedIndexChanged(sender As Object, e As EventArgs) Handles chklstbxWorkspace.SelectedIndexChanged

    Dim entry As Object

    If chklstbxWorkspace.CheckedIndices.Count > 0 Then
        btnStartArchive.Enabled = True
    Else
        btnStartArchive.Enabled = False
    End If
    lblWorkspaceSize.Text = chklstbxWorkspace.CheckedIndices.Count.ToString & " folders selected."


    For Each entry In chklstbxWorkspace.CheckedItems
        fsize += DirectorySize("w:\" & entry.ToString, True)
        lblWorkspaceSize.Text = chklstbxWorkspace.CheckedIndices.Count.ToString & " folders selected.  " & Format(fsize, "###,###,###,###,##0") & " bytes."
    Next
    Application.DoEvents()
End Sub
도움이 되었습니까?

해결책

You could probably use a Dictionary to store previously recorded directories and their sizes so you don't have to calculate the sizes again.

The Dictionary is a collection which stores a key and a value (with the key being unique - since you're looking at folders this should hold up OK, I think but it is something to be aware of). In this case your Key is the folder name and the Value will be the folder size.

Assuming I have a Form called Form1 I can declare my Dictionary like so:

Imports System.Collections.Generic

Public Class Form1
    Dim fileSizesDict As Dictionary(Of String, Long) = New Dictionary(Of String, Long)()

Note the imports of System.Collections.Generic.

And your SelectedIndexChanged handler could then be something like:

Private Sub chklstbxWorkspace_SelectedIndexChanged(sender As Object, e As EventArgs) Handles chklstbxWorkspace.SelectedIndexChanged
    Dim fsize As Long = 0
    Dim entry As Object

    If chklstbxWorkspace.CheckedIndices.Count > 0 Then
        btnStartArchive.Enabled = True
    Else
        btnStartArchive.Enabled = False
    End If
    lblWorkspaceSize.Text = chklstbxWorkspace.CheckedIndices.Count.ToString & " folders selected."


    For Each entry In chklstbxWorkspace.CheckedItems
        If fileSizesDict.ContainsKey(entry.ToString()) Then
            fsize += fileSizesDict(entry.ToString())
        Else
            Dim directorySize As Long = directorySize("w:\" & entry.ToString, True)
            fsize += directorySize

            fileSizesDict.Add(entry.ToString(), directorySize)
        End If
    Next

    lblWorkspaceSize.Text = chklstbxWorkspace.CheckedIndices.Count.ToString & " folders selected.  " & Format(fsize, "###,###,###,###,##0") & " bytes."
End Sub

Couple of things to note:

  1. The first thing we do is search the Dictionary to see if we have already calculated the size of the folder by using the ContainsKey method
  2. If the folder size has been previously calculated then we just get the contents from the Dictionary
  3. Otherwise, we calculate the size and then store it in the Dictionary for future use via the Add method
  4. I moved lblWorkspaceSize.Text = chklstbxWorkspace.CheckedIndices.Count.ToString & " folders selected. " & Format(fsize, "###,###,###,###,##0") & " bytes." outside the For loop....I am not sure of your specific use case but in this case the Label will just be updated with the final calculation results; chop and change this as needed though :-)

Caveat: There is a caveat here in this approach in that if someone has added more files to (or removed some files from) a directory which has previously had its size calculated then we won't pick up the size change as it is not recalculated...I am not sure if this will have a significant impact on your use case or not but just something worth noting.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top