In this example, We want to be able to report progress and cancel the worker when we want, then we want to start it. To do this we do like this:
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Worker1.WorkerReportsProgress = True
Worker1.WorkerSupportsCancellation = True
Worker1.RunWorkerAsync()
End Sub
So now the working will start to work, so now it will call its DoWork event which will be in another thread so it won't interrupt anything else. Since this is only examples to teach you, this thread will loop through an empty for loop one billion times, just to let it do anything that takes some time. For me it takes 4 seconds but If you have a slow computer you can lower the amount of times the loop will loop:
Private Sub Worker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles Worker1.DoWork
For i As Long = 1 To 1000000000
Next
End Sub
Normally when an application is doing something which takes some time to finish and you try to interact with it by for example clicking on it, it will stop to respond, which isn't the case now since the time taking action is done in another thread.
When the backgroundworking is done we often wants to do something, we can then use the RunWorkerCompleted event to do this. In this example we'll just show a messagebox saying it's done:
Private Sub Worker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles Worker1.RunWorkerCompleted
MessageBox.Show("Worker1 is done!")
End Sub
So why don't we just do this in the end of the DoWork event? The reason is that that event is working in another thread and therefor can't access things from another thread, you can still access variables from outside the special thread and the above example would work fin inside the other thread but if we for example want to alter anything on the form we can't, since that is created by another thread. So if we added this at the end of DoWork(inside the out other thread):
Me.Text = "Worker1 is done!"
we would receive this error:
Cross-thread operation not valid: Control 'frmMain' accessed from a thread other than the thread it was created on.
To solve this we do as above, using the RunWorkerCompleted event since that will be run in our main thread and can therefor alter for example our main form.
In the same way we maybe want to alter something from another thread inside our background worker, to do this we have to use the ProgressChanged event. If we alter the DoWork event to this:
Private Sub Worker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles Worker1.DoWork
For i As Long = 1 To 1000000000
Select Case i
Case 1
Worker1.ReportProgress(0)
Case 250000000
Worker1.ReportProgress(25)
Case 500000000
Worker1.ReportProgress(50)
Case 750000000
Worker1.ReportProgress(75)
Case 1000000000
Worker1.ReportProgress(100)
End Select
Next
End Sub
We'll then on some values(1, 250 millions, 500 millions, 750 millions and 1 billion) report the progress (0%, 25%, 50%, 75% and 100%). This can be used in the ProgressChanged event like this:
Private Sub Worker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles Worker1.ProgressChanged
Me.Text = e.ProgressPercentage & "% done"
End Sub
So then we'll get the Progress done outside the special thread so we can use it in our main thread.
That was everything for this tutorial about multi threading, hope you enjoyed it. :)
Edited by James.H, 05 March 2010 - 10:04 AM.


Sign In
Create Account


Back to top









