Results 1 to 4 of 4

Thread: Using the BackgroundWorker Component

  1. #1

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Using the BackgroundWorker Component

    VB version here.

    Create a new Windows Forms project. Add a Label, a ProgressBar and a BackgroundWorker to the form. Set the BackgroundWorker's WorkerReportsProgress property to True. Add the following code then run the project.
    CSharp Code:
    1. private void Form1_Load(object sender, EventArgs e)
    2. {
    3.     // Raise the DoWork event in a worker thread.
    4.     this.backgroundWorker1.RunWorkerAsync();
    5. }
    6.  
    7. // This method is executed in a worker thread.
    8. private void backgroundWorker1_DoWork(object sender,
    9.                                       DoWorkEventArgs e)
    10. {
    11.     BackgroundWorker worker = (BackgroundWorker)sender;
    12.  
    13.     for (int i = 1; i <= 100; i++)
    14.     {
    15.         // Raise the ProgressChanged event in the UI thread.
    16.         worker.ReportProgress(i, i + " iterations complete");
    17.  
    18.         // Perform some time-consuming operation here.
    19.         System.Threading.Thread.Sleep(250);
    20.     }
    21. }
    22.  
    23. // This method is executed in the UI thread.
    24. private void backgroundWorker1_ProgressChanged(object sender,
    25.                                                ProgressChangedEventArgs e)
    26. {
    27.     this.progressBar1.Value = e.ProgressPercentage;
    28.     this.label1.Text = e.UserState as string;
    29. }
    30.  
    31. // This method is executed in the UI thread.
    32. private void backgroundWorker1_RunWorkerCompleted(object sender,
    33.                                                   RunWorkerCompletedEventArgs e)
    34. {
    35.     this.label1.Text = "Operation complete";
    36. }
    Note that if you paste that code into your own form you'll need to go to the Properties window in the designer to attach the event handlers for it to work.

  2. #2

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Passing Data to be Used in the Worker Thread.

    E.g. Perform a loop in the worker thread with a number of iterations determined by the value set in a NumericUpDown:
    CSharp Code:
    1. private void button1_Click(object sender, EventArgs e)
    2. {
    3.     this.backgroundWorker1.RunWorkerAsync(Convert.ToInt32(this.numericUpDown1.Value));
    4. }
    5.  
    6. private void backgroundWorker1_DoWork(object sender,
    7.                                       DoWorkEventArgs e)
    8. {
    9.     BackgroundWorker worker = (BackgroundWorker)sender;
    10.     int iterationCount = 0;
    11.  
    12.     if (e.Argument is int)
    13.     {
    14.         iterationCount = (int)e.Argument;
    15.     }
    16.  
    17.     for (int i = 0; i < iterationCount; i++)
    18.     {
    19.         // Do something here.
    20.     }
    21. }

  3. #3

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Using the BackgroundWorker Component

    Here are two examples that contrast using a BackgroundWorker to update the UI as the work is done and using it to update the UI only once the work is complete:
    CSharp Code:
    1. private void backgroundWorker1_DoWork(object sender,
    2.                                       DoWorkEventArgs e)
    3. {
    4.     BackgroundWorker worker = (BackgroundWorker)sender;
    5.  
    6.     foreach (string filePath in System.IO.Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)))
    7.     {
    8.         worker.ReportProgress(0, System.IO.Path.GetFileName(filePath));
    9.     }
    10. }
    11.  
    12. private void backgroundWorker1_ProgressChanged(object sender,
    13.                                                ProgressChangedEventArgs e)
    14. {
    15.     string fileName = (string)e.UserState;
    16.  
    17.     this.listBox1.Items.Add(fileName);
    18. }
    CSharp Code:
    1. private void backgroundWorker1_DoWork(object sender,
    2.                                       DoWorkEventArgs e)
    3. {
    4.     BackgroundWorker worker = (BackgroundWorker)sender;
    5.     string[] fileNames = System.IO.Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
    6.  
    7.     for (int index = 0; index < fileNames.GetUpperBound(0); index++)
    8.     {
    9.         fileNames[index] = System.IO.Path.GetFileName(fileNames[index]);
    10.     }
    11.  
    12.     e.Result = fileNames;
    13. }
    14.  
    15. private void backgroundWorker1_RunWorkerCompleted(object sender,
    16.                                                   RunWorkerCompletedEventArgs e)
    17. {
    18.     string[] fileNames = (string[])e.Result;
    19.  
    20.     this.listBox1.Items.AddRange(fileNames);
    21. }
    These examples show how you can pass data to the UI from a BackgroundWorker in two different ways without having to explicitly delegate, which is one of the first things everyone has trouble with when multi-threading.

    Note that for the first example to work the WorkerReportsProgress property must be set to True.

  4. #4

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Using the BackgroundWorker Component

    Here is a new example based on the code from the first post. Follow the same instructions as before but this time also set the WorkerSupportsCancellation property of the BackgroundWorker to True and add a Button to the form. Now add this code to your form:
    CSharp Code:
    1. private void Form1_Load(object sender, EventArgs e)
    2. {
    3.     // Raise the DoWork event in a worker thread.
    4.     this.backgroundWorker1.RunWorkerAsync();
    5. }
    6.  
    7. private void backgroundWorker1_DoWork(object sender,
    8.                                       DoWorkEventArgs e)
    9. {
    10.     BackgroundWorker worker = (BackgroundWorker)sender;
    11.  
    12.     for (int i = 1; i <= 100; i++)
    13.     {
    14.         if (worker.CancellationPending)
    15.         {
    16.             // The user has cancelled the background operation.
    17.             e.Cancel = true;
    18.             break;
    19.         }
    20.  
    21.         // Raise the ProgressChanged event in the UI thread.
    22.         worker.ReportProgress(i, i + " iterations complete");
    23.  
    24.         // Perform some time-consuming operation here.
    25.         System.Threading.Thread.Sleep(250);
    26.     }
    27. }
    28.  
    29. // This method is executed in the UI thread.
    30. private void backgroundWorker1_ProgressChanged(object sender,
    31.                                                ProgressChangedEventArgs e)
    32. {
    33.     this.progressBar1.Value = e.ProgressPercentage;
    34.     this.label1.Text = e.UserState as string;
    35. }
    36.  
    37. // This method is executed in the UI thread.
    38. private void backgroundWorker1_RunWorkerCompleted(object sender,
    39.                                                   RunWorkerCompletedEventArgs e)
    40. {
    41.     if (e.Cancelled)
    42.     {
    43.         // The background operation was cancelled.
    44.         this.label1.Text = "Operation cancelled";
    45.     }
    46.     else
    47.     {
    48.         // The background operation completed normally.
    49.         this.label1.Text = "Operation complete";
    50.     }
    51. }
    52.  
    53. private void button1_Click(object sender, EventArgs e)
    54. {
    55.     // Only cancel the background operation if there is a background operation in progress.
    56.     if (this.backgroundWorker1.IsBusy)
    57.     {
    58.         this.backgroundWorker1.CancelAsync();
    59.     }
    60. }
    If you run the project and let it go then the ProgressBar will fill and eventually the Label will report that the operation completed. If, however, you click the Button at some point, the Progressbar will halt and the Label will report that the operation was cancelled.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width