ProgressBar / Multithreading Issue

TwistedHope

New member
Joined
Dec 13, 2007
Messages
2
Location
Ohio
Programming Experience
3-5
Hello all.

I thought my problem I'm having must be common, but I couldn't find anything useful via Google. I'm building a find/replace application, and while the find/replace method is running, I want to keep the user informed on the progress with a ProgressBar. While the find/replace routine is executing the ProgessBar updates itself after the find/replace is completed for each individual file (it does this find/replace for all files in a specified directory). The ProgressBar doesn't run smoothly through this process and looks like crap. For example, in Vista the progress bars have the glare that goes over the progress bar every couple seconds and when this happens it definitely looks like the program is lagging and doesn't appear smooth.

I tried running this process using a new thread, and also tried it using the BackgroundWorker. Both methods worked to fix the smoothness issue with the ProgressBar, but severely slowed down the speed at which the find/replace process was ran (from roughly 8 seconds to about 75 seconds). Is there any way to fix this? Also note that when using the BackgroundWorker I only called ReportProgress for it after each file had executed the find/replace routine (so maybe 10 times total), so I wasn't updating the UI too much which would explain a slowdown.

I would rather not post code unless absolutely necessary. Let me know if it is needed.

Thanks in Advance!
Matt
 
Here are a couple snippets, if there are any problems, it will be in here as this is the code pertaining to the BackgroundWorker. Everything else has been verified as working correctly:

VB.NET:
Private Sub btnExecute_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExecute.Click
        prbProgress.Minimum = 0
        prbProgress.Maximum = 100
        prbProgress.Value = 0
        prbProgress.Step = 1

        'START THE PROGRESS BACKGROUND WORKER
        wkrProgress.RunWorkerAsync()
    End Sub

Private Sub wkrProgress_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles wkrProgress.DoWork
        'NOTE THAT THIS TRY/CATCH WILL BE REMOVED LATER -- IT IS ONLY HERE FOR TESTING
        Try
            Dim StartTime As New DateTime
            Dim EndTime As New DateTime
            mintReplaceCount = 0

            'DETERMINE IF FIND/REPLACE WILL BE SINGLE OR MULTI LINE
            If txtFind.Lines.Length > 1 OrElse txtReplace.Lines.Length > 1 Then
                mblnMultiline = True
            Else
                mblnMultiline = False
            End If

            'FIND TOTAL FILE SIZE
            lngTotalFileSize = 0
            lngHandledFileSize = 0
            For Each FilePath As String In Directory.GetFiles(txtFile.Text)
                lngTotalFileSize += FileLen(FilePath)
            Next

            StartTime = Now

            If IO.File.Exists(txtFile.Text) AndAlso Not New FileInfo(txtFile.Text).IsReadOnly Then
                FileFindAndReplace(txtFile.Text)
            ElseIf Directory.Exists(txtFile.Text) Then
                For Each FilePath As String In Directory.GetFiles(txtFile.Text)
                    Dim Attributes As FileAttributes = File.GetAttributes(FilePath)

                    If Not ((Attributes And FileAttributes.ReadOnly) = FileAttributes.ReadOnly) AndAlso Not ((Attributes And FileAttributes.Hidden) = FileAttributes.Hidden) AndAlso Not ((Attributes And FileAttributes.System) = FileAttributes.System) Then
                        FileFindAndReplace(FilePath)
                    End If
                    lngHandledFileSize += FileLen(FilePath)

                    'wkrProgress.ReportProgress(CInt(Math.Round((lngHandledFileSize / lngTotalFileSize) * 100)))
                Next
            Else
                MessageBox.Show("Invalid File/Directory Selection")
                Exit Sub
            End If

            EndTime = Now

            MessageBox.Show(mintReplaceCount.ToString & " replacements | " & CStr((EndTime.Ticks - StartTime.Ticks) / 10000) & " ms")
        Catch ex As Exception
            MessageBox.Show(ex.ToString)
        End Try
    End Sub
 
Back
Top