Tuesday, April 17, 2012

Background Worker

BackgroundWorker Class for Multithreading:
The BackgroundWorker class allows you to run an operation on a separate, dedicated thread. Time-consuming operations like downloads and database transactions can cause your user interface (UI) to seem as it has stopped responding while they are running. When you want a responsive UI and you are faced with long delays associated with such operations, the BackgroundWorker class provides a convenient solution.

You can create the BackgroundWorker programmatically or you can drag it onto your form from the Components tab of the Toolbox. If you create the BackgroundWorker in the Windows Forms Designer, it will appear in the Component Tray, and its properties will be displayed in the Properties window.

Pocedure To use the BackgroundWorker class


1. At the class level, create an instance of the BackgroundWorker class.
                  //C#

 BackgroundWorker bw = new BackgroundWorker(); 
          'VB
          Dim bw As BackgroundWorker = New BackgroundWorker

2. Specify whether you want the background operation to allow cancellation and to report progress.
 //C#
bw.WorkerSupportsCancellation = true;
bw.WorkerReportsProgress = true;
'VB
bw.WorkerSupportsCancellation = True
bw.WorkerReportsProgress = True
3. 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 theDoWorkEventArgs 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.
//C#
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));
        }
    }
}
'VB
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

4. 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.
//C#
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    this.tbProgress.Text = (e.ProgressPercentage.ToString() + "%");
}
'VB
Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
    Me.tbProgress.Text = e.ProgressPercentage.ToString() & "%"
End Sub

5. 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.
 //C#
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!";
    }
}
'VB
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

 6. Add the event handlers to the BackgroundWorker instance.
The following example shows how to add the event handlers to the DoWork, ProgressChanged, and RunWorkerCompleted events.
 //C# 
bw.DoWork +=
    new DoWorkEventHandler(bw_DoWork);
bw.ProgressChanged +=
    new ProgressChangedEventHandler(bw_ProgressChanged);
bw.RunWorkerCompleted +=
    new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
'VB
AddHandler bw.DoWork, AddressOf bw_DoWork
AddHandler bw.ProgressChanged, AddressOf bw_ProgressChanged
AddHandler bw.RunWorkerCompleted, AddressOf bw_RunWorkerCompleted

7. Start running the background operation by calling the RunWorkerAsync method.
//C#
private void buttonStart_Click(object sender, RoutedEventArgs e)
{
    if (bw.IsBusy != true)
    {
        bw.RunWorkerAsync();
    }
}
'VB
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

8. Cancel the background operation by calling the CancelAsync method.
//C#
private void buttonCancel_Click(object sender, RoutedEventArgs e)
{
    if (bw.WorkerSupportsCancellation == true)
    {
        bw.CancelAsync();
    }
}
'VB
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

1 comment: