November 24, 2014
Hot Topics:

Safe Multithreading with the BackgroundWorker Component

  • October 12, 2005
  • By Paul Kimmel
  • Send Email »
  • More Articles »

In the physical world, two workers are twice as productive as one. In the programming world, using additional threads safely can increase an application's productivity and add a depth and richness that help the user to be more productive too. The drawback has been that multi-threaded applications typically have been harder to write and debug. This is still true to some extent; but with .NET, multithreading is getting easier to use.

Early editions of .NET introduced thread pools, and .NET 2.0 introduces the BackgroundWorker component. The BackgroundWorker component permits you to incorporate additional worker threads, and it isn't much harder to use then the old standby, the Timer component.

This article demonstrates how to use the BackgroundWorker component safely, including how to marshal control from the worker thread back to the Windows Forms thread.

Implementing the DoWorkEventHandler

Because the BackgroundWorker class is a component, you can drag and drop it onto a Windows Form or UserControl and wire up event handlers visually. If you don't have a form or UserControl, you can declare and create an instance of the BackgroundWorker and bind its event properties with code.

The BackgroundWorker component is defined in the System.ComponentModel namespace. To use the BackgroundWorker, you can add an Imports statement or use the namespace in the declaration and initialization statement. Here is an example:

Dim worker as System.ComponentModel.BackgroundWorker
worker  = new System.ComponentModel.BackgroundWorker

The worker thread is expressed as a delegate wired to the BackgroundWorker.DoWork event property. The following is the signature of the delegate (event handler) for the DoWork property:

Sub DoWork(Sender As Object, _
           e As System.ComponentModel.DoWorkEventArgs)

Any subroutine with the two argument types in the order shown can be assigned to the DoWork event property. The BackgroundWorker component also has a ProgressChanged event property, and you can signal the relative progress of the background thread by wiring an event handler to the ProgressChanged event. The following is the signature for ProgressChanged:

Sub ProgressChanged(sender As Object, _
   e As System.ComponentModel.ProgressChangedEventArgs)

Listing 1 shows how to create an instance of the BackgroundWorker component and wire up DoWork and ProgressChanged in the Form's OnLoad event.

Listing 1: Create and Wire Up DoWork and ProgressChanged Events for BackgroundWorker Component

Private worker As BackgroundWorker
Private Sub Form1_Load(ByVal sender As System.Object, _
   ByVal e As System.EventArgs) Handles MyBase.Load
   worker = New BackgroundWorker()
   worker.WorkerReportsProgress = True
   AddHandler worker.DoWork, New _
      DoWorkEventHandler(AddressOf OnWork)
   AddHandler worker.ProgressChanged, _
      New ProgressChangedEventHandler(AddressOf OnProgressChanged)
End Sub

Running the Worker Thread

To start the worker thread, you invoke the BackgroundWorker.RunWorkerAsync method. This example adds ProgressBar to a form and uses a button to simulate an event that initiates the background worker process. The following snippet demonstrates how to start the background thread:

Private Sub Button1_Click(ByVal sender As System.Object, _
   ByVal e As System.EventArgs) Handles Button1.Click
   worker.RunWorkerAsync()
End Sub

Figure 1 shows the simple example Form. The ProgressBar shown will be updated indirectly by an event the BackgroundWorker component raises.

Figure 1: Example Form with ProgressBar





Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel