Published articles on other web sites*

Published articles on other web sites*

Use a Background Worker


How to: Use a Background Worker

Silverlight
The Silverlight BackgroundWorker1 class provides an easy way to run time-consuming operations on a background thread. The BackgroundWorker1 class enables you to check the state of the operation and it lets you cancel the operation.
When you use the BackgroundWorker1 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

  1. At the class level, create an instance of the BackgroundWorker1 class.
    BackgroundWorker bw = new BackgroundWorker();
    
  2. Specify whether you want the background operation to allow cancellation and to report progress.
    bw.WorkerSupportsCancellation = true;
    bw.WorkerReportsProgress = true;
    
  3. Create an event handler for the background worker's DoWork2 event.
    The DoWork2 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 Argument3 property of the DoWorkEventArgs4object that is passed to the event handler.
    To report progress back to the calling process, call the ReportProgress5 method and pass it a completion percentage from 0 to 100. Calling the ReportProgress5 method raises the ProgressChanged6 event, which you handle separately.
    Note Note:
    If the background worker's WorkerReportsProgress7 property is not set to true and you call the ReportProgress5 method, an exception will occur.
    To determine if there is a pending request to cancel the background operation, check the CancellationPending8 property of the BackgroundWorker1 object. If the property is true, the CancelAsync9 method was called. Set theBackgroundWorker1 object's Cancel10 property to true and stop the operation.
    To pass data back to the calling process, set the Result11 property of the DoWorkEventArgs4 object that is passed to the event handler. This value can be read when the RunWorkerCompleted12 event is raised at the end of the operation.
    private void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;
    
        for (int i = 1; (i <= 10); i++)
        {
            if ((worker.CancellationPending == true))
            {
                e.Cancel = true;
                break;
            }
            else
            {
                // Perform a time consuming operation and report progress.
                System.Threading.Thread.Sleep(500);
                worker.ReportProgress((i * 10));
            }
        }
    }
    
    
    
  4. Create an event handler for the background worker's ProgressChanged6 event.
    In the ProgressChanged6 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 ProgressPercentage13 property of the ProgressChangedEventArgs14 object that was passed to the event handler.
    private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        this.tbProgress.Text = (e.ProgressPercentage.ToString() + "%");
    }
    
    
    
  5. Create an event handler for the RunWorkerCompleted12 event.
    The RunWorkerCompleted12 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 Error15 property of the RunWorkerCompletedEventArgs16 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 Cancelled17 property of the RunWorkerCompletedEventArgs16 object that was passed to the event handler. If the property is true, the CancelAsync9 method was called.
    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if ((e.Cancelled == true))
        {
            this.tbProgress.Text = "Canceled!";
        }
    
        else if (!(e.Error == null))
        {
            this.tbProgress.Text = ("Error: " + e.Error.Message);
        }
    
        else
        {
            this.tbProgress.Text = "Done!";
        }
    }
    
    
    
  6. Add the event handlers to the BackgroundWorker1 instance's events.
    The following example shows how to add the event handlers to the DoWork2ProgressChanged6, and RunWorkerCompleted12 events.
    bw.DoWork += 
        new DoWorkEventHandler(bw_DoWork);
    bw.ProgressChanged += 
        new ProgressChangedEventHandler(bw_ProgressChanged);
    bw.RunWorkerCompleted += 
        new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
    
  7. Start running the background operation by calling the RunWorkerAsync18 method.
    private void buttonStart_Click(object sender, RoutedEventArgs e)
    {
        if (bw.IsBusy != true)
        {
            bw.RunWorkerAsync();
        }
    }
    
    
    
  8. Cancel the background operation by calling the CancelAsync9 method.
    private void buttonCancel_Click(object sender, RoutedEventArgs e)
    {
        if (bw.WorkerSupportsCancellation == true)
        {
            bw.CancelAsync();
        }
    }
    
    
    

The following example shows how to use the BackgroundWorker1 class. In the example, the background operation runs the Sleep19 method and reports progress to the user interface. The background worker is configured to allow cancellation.
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace SL_BackgroundWorker_CS
{
    public partial class Page : UserControl
    {
        private BackgroundWorker bw = new BackgroundWorker();

        public Page()
        {
            InitializeComponent();

            bw.WorkerReportsProgress = true;
            bw.WorkerSupportsCancellation = true;
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        }
        private void buttonStart_Click(object sender, RoutedEventArgs e)
        {
            if (bw.IsBusy != true)
            {
                bw.RunWorkerAsync();
            }
        }
        private void buttonCancel_Click(object sender, RoutedEventArgs e)
        {
            if (bw.WorkerSupportsCancellation == true)
            {
                bw.CancelAsync();
            }
        }
        private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            for (int i = 1; (i <= 10); i++)
            {
                if ((worker.CancellationPending == true))
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    // Perform a time consuming operation and report progress.
                    System.Threading.Thread.Sleep(500);
                    worker.ReportProgress((i * 10));
                }
            }
        }
        private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if ((e.Cancelled == true))
            {
                this.tbProgress.Text = "Canceled!";
            }

            else if (!(e.Error == null))
            {
                this.tbProgress.Text = ("Error: " + e.Error.Message);
            }

            else
            {
                this.tbProgress.Text = "Done!";
            }
        }
        private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.tbProgress.Text = (e.ProgressPercentage.ToString() + "%");
        }
    }
}


<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>

No comments:

Post a Comment