• (2 Pages)
  • +
  • 1
  • 2

The Background Worker How to use a background worker. Rate Topic: ***** 2 Votes

#1 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2271
  • View blog
  • Posts: 9,499
  • Joined: 29-May 08

Post icon  Posted 23 February 2009 - 02:37 PM

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.
Dim m_CountTo As Integer = 0' How many time to loop.



Double Click on the start button and enter.
 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
 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.
 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
 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.
 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
  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.
 ' 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.

   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:

Is This A Good Question/Topic? 4
  • +

Replies To: The Background Worker

#2 lowrent2000  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 25-February 09

Posted 08 April 2009 - 09:39 PM

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.
Was This Post Helpful? 0
  • +
  • -

#3 KevinPrecht  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 12-May 09

Posted 15 May 2009 - 03:34 PM

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

:)
Was This Post Helpful? 0
  • +
  • -

#4 Sc00by22  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 25
  • Joined: 09-September 09

Posted 15 September 2009 - 09:00 AM

Thanks so much! Exactly what I have been needing for ages!
Was This Post Helpful? 0
  • +
  • -

#5 Guest_Code Learner*


Reputation:

Posted 30 March 2010 - 05:50 AM

Awesome Tutorial.....Thanks a lot!!!
Was This Post Helpful? 0

#6 TheRafi  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 02-October 10

Posted 02 October 2010 - 07:29 PM

Thank you so much for this great tutorial.

Here is a modification I made to update a listbox instead of the label

    ' The delegate
    Delegate Sub SetListBox_Delegate(ByVal [ListBox] As ListBox, ByVal [text] As String)

    ' The delegates subroutine.
    Private Sub SetListBox_ThreadSafe(ByVal [ListBox] As ListBox, 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 [ListBox].InvokeRequired Then
            Dim MyDelegate As New SetListBox_Delegate(AddressOf SetListBox_ThreadSafe)
            Me.Invoke(MyDelegate, New Object() {[ListBox], [text]})
        Else
            [ListBox].Items.Add([text])
        End If
    End Sub

This post has been edited by TheRafi: 02 October 2010 - 07:59 PM

Was This Post Helpful? 0
  • +
  • -

#7 mvdsa  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 29-November 11

Posted 08 December 2011 - 06:06 AM

hi tHERE\

Where do i put my code in now to load in the background.. or am i being stupid :)/>

All i want to do is load a very big Form with graphics which takes a few seconds to load ..
but it looks realy bad when loading.

Please help

This post has been edited by macosxnerd101: 06 May 2013 - 12:18 PM
Reason for edit:: Removed quote

Was This Post Helpful? 0
  • +
  • -

#8 dhaggy1980  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 21-May 12

Posted 28 May 2012 - 11:37 AM

Awesome Tut man I have been trying for days now to figure out this background worker to work with ftp and it works great. Except it slows down when I put a label in. It will still upload but, I think it uploads according to the labels text. I don't need that stupid label anyway LOL. But all in all it works great.
Was This Post Helpful? 0
  • +
  • -

#9 deavmi  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 06-May 13

Posted 06 May 2013 - 12:15 PM

Dude keep your code in the same place, the cross-thread thing won't show up when you are running the application normally and not debugging in VB, it will work as fine.

This post has been edited by macosxnerd101: 06 May 2013 - 12:18 PM
Reason for edit:: Removed quote

Was This Post Helpful? 0
  • +
  • -

#10 Big_Android_Doris  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 30-May 13

Posted 30 May 2013 - 12:47 PM

Why is the huge, complex mess of code needed?

If MS wanted us to use this extremely common feature: Run This Code In The Background

Why can't the entire mess just be one line of code:
Call RunInTheBackground(mySubName)

Done.

Sheezess. I can't invest all this time, coding, and debugging... just to do something that should ALREADY
be a built-in call.
Was This Post Helpful? 1
  • +
  • -

#11 modi123_1  Icon User is online

  • Suitor #2
  • member icon



Reputation: 9574
  • View blog
  • Posts: 36,262
  • Joined: 12-June 08

Posted 30 May 2013 - 12:53 PM

If you can't invest the time then it seems you don't need to use it?

The tutorial is not a mess or that complex. Part of it is setting up the GUI events, one part is for the background worker events, and the other for what to do when the background worker runs.
Was This Post Helpful? 0
  • +
  • -

#12 Big_Android_Doris  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 30-May 13

Posted 30 May 2013 - 12:53 PM

Why does this article contain countless sentence fragments that make no sense?
Is the English?

> VB.Net doesn't like use talking
> A background worker allow the designer
> To use comment out the line code
> Now that all it takes to use a Background Worker
Was This Post Helpful? -1
  • +
  • -

#13 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10807
  • View blog
  • Posts: 40,287
  • Joined: 27-December 08

Posted 30 May 2013 - 12:56 PM

Are you here just to criticize and troll? Or are you here to participate in the forums and community?
Was This Post Helpful? 0
  • +
  • -

#14 Big_Android_Doris  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 30-May 13

Posted 30 May 2013 - 01:00 PM

View Postmacosxnerd101, on 30 May 2013 - 12:56 PM, said:

Are you here just to criticize and troll? Or are you here to participate in the forums and community?


People are allowed to write broken English that's VERY hard to read...but no one is allowed to correct it?

Wow. Great site.
Was This Post Helpful? 0
  • +
  • -

#15 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10807
  • View blog
  • Posts: 40,287
  • Joined: 27-December 08

Posted 30 May 2013 - 01:04 PM

Well, if you have legitimate complaints, you're welcome to shoot me a PM. You just joined the site to complain though. Seriously- please don't feel obligated to post if you just want to troll. Our members put a lot of effort into their tutorials. Constructive criticisms are fine. It seems like you're just complaining to complain and seek attention though.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2