School Assignment? Project Due Tomorrow? Chat LIVE With A Programming Expert!

Welcome to Dream.In.Code
Become an Expert!

Join 307,148 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 1,731 people online right now. Registration is fast and FREE... Join Now!




The Background Worker

 
Reply to this topicStart new topic

> The Background Worker, How to use a background worker.

AdamSpeight2008
Group Icon



post 23 Feb, 2009 - 01:37 PM
Post #1


The Background Worker

What is a background worker?

A background worker allow the designer to offload some of processing on another thread, which can make the UI feel more responsive.

How to use a background worker.

For this demonstration you'll have to create a new windows application project, until you grasped the basics.
Add two buttons to the form, name them Start_Button & Stop_Button
Add a progress bar
Add a label, named lbl_Status
Add a Background worker.

Set then enable state of the stop button to False

In the properties of the background worker set the following properties to true.
WorkerSupportsCancellation & WorkerReportsProgress

Now view to code of the form and add the following code the top.
CODE

Dim m_CountTo As Integer = 0' How many time to loop.


Double Click on the start button and enter.
CODE

Private Sub Start_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Start_Button.Click
  'Set the count to 30
  m_CountTo = 30
  ' Disable the start button
  Me.Start_Button.Enabled = False
  ' Enable to stop button
  Me.Stop_Button.Enabled = True
  ' Start the Background Worker working
  My_BgWorker.RunWorkerAsync()
End Sub


Double Click the stop button
CODE

Private Sub Stop_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Stop_Button.Click
  ' Is the Background Worker do some work?
  If My_BgWorker.IsBusy Then
   'If it supports cancellation, Cancel It
   If My_BgWorker.WorkerSupportsCancellation Then
    ' Tell the Background Worker to stop working.
    My_BgWorker.CancelAsync()
   End If
  End If
  ' Enable to Start Button
  Me.Start_Button.Enabled = True
  ' Disable to Stop Button
  Me.Stop_Button.Enabled = False
End Sub


Then Next section of code is the code that is to be run in the background.
CODE

Private Sub My_BgWorker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles My_BgWorker.DoWork

  For i As Integer = 0 To m_CountTo
   ' Has the background worker be told to stop?
   If My_BgWorker.CancellationPending Then
    ' Set Cancel to True
    e.Cancel = True
    Exit For
   End If
   System.Threading.Thread.Sleep(1000) ' Sleep for 1 Second
   ' Report The progress of the Background Worker.
   My_BgWorker.ReportProgress(CInt((i / m_CountTo) * 100))
  Next
End Sub


Note: That the My_BgWorker.ReportProgress only excepts integer values between 0 to 100 inclusive. So you'll have to scale your value to this range.

Now to add the code to update the Progress Bar
CODE

Private Sub My_BgWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles My_BgWorker.ProgressChanged
  ' Update the progress bar
  Me.ProgressBar1.Value = e.ProgressPercentage
End Sub


Now for the code that runs after the Background Worker is finished.
CODE

Private Sub My_BgWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles My_BgWorker.RunWorkerCompleted
  If e.Cancelled Then
   Me.Lbl_Status.Text = "Cancelled"
  Else
   Me.Lbl_Status.Text = "Completed"
  End If
End Sub



Now that all it takes to use a Background Worker.

For the more adventurous of you
Let's use that label and display a percentage of completion.


Add this extra line of code to the DoWork procedure
CODE

  My_BgWorker.ReportProgress(CInt((i / m_CountTo) * 100))
   Me.Lbl_Status.Text = FormatPercent(i / m_CountTo, 2) ' Show Percentage in Label

And Run.

You get the following error Cross-thread operation not valid: Control 'Lbl_Status' accessed from a thread other than the thread it was created on.
Why?

Because we are using a background worker and we're attempting to access controls on a different thread (The UI or form).
VB.Net doesn't like use talking to objects on another thread directly, so have to go Indirectly through a intermediary called a Delegate
It is possible to turn it off and allow them but that's just asking for trouble.
I'll show you the proper and correct way to achieve this, by adding a new subroutine and a delegate.
A delegate helps to communicate to objects of a different thread;- It delegates the talking between the different threads.

Go back to the code and enter the following code.
CODE

' The delegate
Delegate Sub SetLabelText_Delegate(ByVal [Label] As Label, ByVal [text] As String)

' The delegates subroutine.
Private Sub SetLabelText_ThreadSafe(ByVal [Label] As Label, ByVal [text] As String)
  ' InvokeRequired required compares the thread ID of the calling thread to the thread ID of the creating thread.
  ' If these threads are different, it returns true.
  If [Label].InvokeRequired Then
   Dim MyDelegate As New SetLabelText_Delegate(AddressOf SetLabelText_ThreadSafe)
   Me.Invoke(MyDelegate, New Object() {[Label], [text]})
  Else
   [Label].Text = [text]
  End If
End Sub

To use comment out the line code in Do Work routine that caused the error, then enter the following.

CODE

   My_BgWorker.ReportProgress(CInt((i / m_CountTo) * 100))
   ' Me.Lbl_Status.Text = FormatPercent(i / m_CountTo, 2)
   SetLabelText_ThreadSafe(Me.Lbl_Status, FormatPercent(i / m_CountTo, 2))


And run, now you have the label displaying the percentage.


Now you have the Background Worker in your Code Ninja arsenal. ph34r.gif
Go to the top of the page
+Quote Post


Register to Make This Ad Go Away!

lowrent2000
*



post 8 Apr, 2009 - 08:39 PM
Post #2
Greetings,
Thanks for the post, very helpful. I want to run an event timer in the tool strip. Timer works if there is no event to time. Stops when the event starts. How would you exacute a timer event within the background manager. Tried this, no good. Thanks for any help you can give.

Public Class Form1
Dim startTime As DateTime
Dim span As TimeSpan = DateTime.Now.Subtract(startTime)
Dim clock As String

Private Sub Start_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Start_Button.Click
Me.bgwTimer.RunWorkerAsync()
End Sub

Private Sub bgwTimer_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwTimer.DoWork
Me.Timer1.Start()
End Sub

Private Sub Timer1_Tick(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Timer1.Tick
Me.bgwTimer.ReportProgress(span.Milliseconds)
End Sub

Private Sub bgwTimer_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgwTimer.ProgressChanged
clock = e.ToString
Me.ToolStripLabel1.Text = span.Minutes.ToString & ":" & _
span.Seconds.ToString & "." & span.Milliseconds
End Sub
End Class

Noi errors, just terminates at the do work event. other foreground and background events uneffectived.
Go to the top of the page
+Quote Post

KevinPrecht
*



post 15 May, 2009 - 02:34 PM
Post #3
I just would like to say that this is EXACTLY the information that I was trying to figure out on my own with starting individual threads and then trying to keep track of them.

thanks a bunch for this very clear and helpful tutorial!

Kevin

smile.gif
Go to the top of the page
+Quote Post

Sc00by22
*



post 15 Sep, 2009 - 08:00 AM
Post #4
Thanks so much! Exactly what I have been needing for ages!
Go to the top of the page
+Quote Post


Fast ReplyReply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 


Lo-Fi Version Time is now: 11/21/09 04:03PM

Live Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month