How to: Use a Background Worker
The Silverlight BackgroundWorker class provides an easy way to run time-consuming operations on a background thread. The BackgroundWorker class enables you to check the state of the operation and it lets you cancel the operation.
When you use the BackgroundWorker class, you can indicate operation progress, completion, and cancellation in the Silverlight user interface. For example, you can check whether the background operation is completed or canceled and display a message to the user.
To use the BackgroundWorker class
-
At the class level, create an instance of the BackgroundWorker class.
-
Specify whether you want the background operation to allow cancellation and to report progress.
-
Create an event handler for the background worker's DoWork event.
The DoWork event handler is where you run the time-consuming operation on the background thread. Any values that are passed to the background operation are passed in the Argument property of the DoWorkEventArgs object that is passed to the event handler.
To report progress back to the calling process, call the ReportProgress method and pass it a completion percentage from 0 to 100. Calling the ReportProgress method raises the ProgressChanged event, which you handle separately.
Note:
If the background worker's WorkerReportsProgress property is not set to true and you call the ReportProgress method, an exception will occur.
To determine if there is a pending request to cancel the background operation, check the CancellationPending property of the BackgroundWorker object. If the property is true, the CancelAsync method was called. Set the BackgroundWorker object's Cancel property to true and stop the operation.
To pass data back to the calling process, set the Result property of the DoWorkEventArgs object that is passed to the event handler. This value can be read when the RunWorkerCompleted event is raised at the end of the operation.
Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Dim worker As BackgroundWorker = CType(sender, BackgroundWorker) For i = 1 To 10 If bw.CancellationPending = True Then e.Cancel = True Exit For Else ' Perform a time consuming operation and report progress. System.Threading.Thread.Sleep(500) bw.ReportProgress(i * 10) End If Next End Sub
-
Create an event handler for the background worker's ProgressChanged event.
In the ProgressChanged event handler, add code to indicate the progress, such as updating the user interface.
To determine what percentage of the operation is completed, check the ProgressPercentage property of the ProgressChangedEventArgs object that was passed to the event handler.
-
Create an event handler for the RunWorkerCompleted event.
The RunWorkerCompleted event is raised when the background worker has completed. Depending on whether the background operation completed successfully, encountered an error, or was canceled, update the user interface accordingly.
To determine whether an error occurred, check the Error property of the RunWorkerCompletedEventArgs object that was passed to the event handler. If an error occurred, this property contains the exception information.
If the background operation allows cancellation and you want to check whether the operation was canceled, check the Cancelled property of the RunWorkerCompletedEventArgs object that was passed to the event handler. If the property is true, the CancelAsync method was called.
-
Add the event handlers to the BackgroundWorker instance's events.
The following example shows how to add the event handlers to the DoWork, ProgressChanged, and RunWorkerCompleted events.
-
Start running the background operation by calling the RunWorkerAsync method.
-
Cancel the background operation by calling the CancelAsync method.
The following example shows how to use the BackgroundWorker class. In the example, the background operation runs the Sleep method and reports progress to the user interface. The background worker is configured to allow cancellation.
Imports System.ComponentModel Partial Public Class Page Inherits UserControl Private bw As BackgroundWorker = New BackgroundWorker Public Sub New() InitializeComponent() bw.WorkerReportsProgress = True bw.WorkerSupportsCancellation = True AddHandler bw.DoWork, AddressOf bw_DoWork AddHandler bw.ProgressChanged, AddressOf bw_ProgressChanged AddHandler bw.RunWorkerCompleted, AddressOf bw_RunWorkerCompleted End Sub Private Sub buttonStart_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) If Not bw.IsBusy = True Then bw.RunWorkerAsync() End If End Sub Private Sub buttonCancel_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) If bw.WorkerSupportsCancellation = True Then bw.CancelAsync() End If End Sub Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Dim worker As BackgroundWorker = CType(sender, BackgroundWorker) For i = 1 To 10 If bw.CancellationPending = True Then e.Cancel = True Exit For Else ' Perform a time consuming operation and report progress. System.Threading.Thread.Sleep(500) bw.ReportProgress(i * 10) End If Next End Sub Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) If e.Cancelled = True Then Me.tbProgress.Text = "Canceled!" ElseIf e.Error IsNot Nothing Then Me.tbProgress.Text = "Error: " & e.Error.Message Else Me.tbProgress.Text = "Done!" End If End Sub Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Me.tbProgress.Text = e.ProgressPercentage.ToString() & "%" End Sub End Class
<UserControl x:Class="SL_BackgroundWorker_CS.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <StackPanel Height="30" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10" > <Button x:Name="buttonStart" Content="Start" Click="buttonStart_Click" Width="80" Height="30"/> <Button x:Name="buttonCancel" Content="Cancel" Click="buttonCancel_Click" Width="80" Height="30"/> </StackPanel> <StackPanel Margin="10,50,0,0" Orientation="Horizontal"> <TextBlock Text="Progress: "/> <TextBlock x:Name="tbProgress"/> </StackPanel> </Grid> </UserControl>
<UserControl x:Class="SL_BackgroundWorker_VB.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <StackPanel Height="30" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10" > <Button x:Name="buttonStart" Content="Start" Click="buttonStart_Click" Width="80" Height="30"/> <Button x:Name="buttonCancel" Content="Cancel" Click="buttonCancel_Click" Width="80" Height="30"/> </StackPanel> <StackPanel Margin="10,50,0,0" Orientation="Horizontal"> <TextBlock Text="Progress: " /> <TextBlock x:Name="tbProgress" /> </StackPanel> </Grid> </UserControl>