I use Visual Studio 2013 for Visual Basic and I'm struggling to debug my multi-threaded program.
I am using a BackgroundWorker, which appears to work differently to how I think it should.
I don't understand why my program halts after processing only the first entry in my ArrayList called arFileName
.
The For Each
statement in BackgroundWorker1.DoWork procedure fails to iterate through the entire arFileName
in the following code:
Private Sub btnRun_Click(sender As Object, e As EventArgs) Handles btnSelectCsv.Click
'arFileName is ArrayList and it has enormous counts
ProgressBar1.Maximum = arFileName.Count
Me.Cursor = Cursors.WaitCursor
'Do background
BackgroundWorker1.RunWorkerAsync()
Me.Cursor = Cursors.Arrow
MessageBox.Show("Finished!", "info", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) _
Handles BackgroundWorker1.DoWork
Dim arNotFoundFile As New ArrayList
'Confirm file exists
For Each filename As String In arFileName ' Here!
If Not IO.File.Exists(filename) Then
arNotFoundFile.Add(filename)
ProgressBar1.Value = ProgressBar1.Value + 1
End If
Next
End Sub
The backgroundworker must be set to report its progresses
BackgroundWorker1.WorkerReportsProgress = True
Then, a typical implementation could be as follows:
Dim progress As Integer = 0
Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
While (progress < 100)
' YOUR CODE HERE
progress += 1
BackgroundWorker1.ReportProgress(progress)
End While
End Sub
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
' YOUR PROGRESSBAR VALUE HERE, USING progress VARIABLE
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
MessageBox.Show("Work completed")
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
BackgroundWorker1.WorkerReportsProgress = True
BackgroundWorker1.RunWorkerAsync()
End Sub
As you can see, i've defined a progress variable, which will keep track of the percentage of work done. After we start the backgroundworker (which i do into the Form_Load event) with RunWorkerAsync, we could keep track of its progresses by the ProgressChanged event: here, we use the progress variable, modified by our work (DoWork). You could use it to set the progressbar value property. Finally, when all its done, we emit the message into the proper event, i.e. RunWorkerCompleted