This page was last reviewed on Apr 5, 2023.
Dot Net Perls
BackgroundWorker. This makes threads easy to implement in Windows Forms. Intensive tasks need to be done on another thread so the UI does not freeze.
Type notes. With BackgroundWorker, it is necessary to post messages and update the user interface when the task is done. There is some complexity to this—but it makes sense with an example.
DoWork. Here we must look at the C# view of your file, where we will see the DoWork method. The backgroundWorker1_DoWork event is generated when you double-click on DoWork.
Step 1 Click on BackgroundWorker. Look at the gray bar near the bottom of your window. A BackgroundWorker will appear there.
Step 2 Highlight backgroundWorker1. Click on the backgroundWorker1 item in the gray bar on the bottom. Now, look at the Properties panel.
Step 3 Look for the lightning bolt. You will see a lightning bolt icon in the Properties pane. Then, double-click on DoWork.
Note The Thread.Sleep method will pause the execution of the BackgroundWorker. It will show us threading is functioning.
using System; using System.ComponentModel; using System.Windows.Forms; using System.Threading; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { Thread.Sleep(1000); // One second. } } }
Properties. I want to emphasize the Argument, Result, and the RunWorkerAsync methods. These are the properties of BackgroundWorker required to accomplish anything.
DoWorkEventArgs e Contains e.Argument and e.Result. It is used to access those properties. e.Argument Used to get the parameter reference received by RunWorkerAsync. e.Result Check to see what the BackgroundWorker processing did. backgroundWorker1.RunWorkerAsync Called to start a process on the worker thread.
RunWorkerAsync. We can add arguments and return values to BackgroundWorker. We need to add arguments, invoke the BackgroundWorker, and then receive the results of the thread.
Tip Changing variables from multiple threads at once often leads to bugs. A variable can become invalid.
Detail An example argument is created. You will have something more important and complex in your program.
Detail This can be called anywhere in your code. We use a constructor, but that isn't important.
public partial class Form1 : Form { public Form1() { InitializeComponent(); // // Example argument object // TestObject test = new TestObject { OneValue = 5, TwoValue = 4 }; // // Send argument to our worker thread // backgroundWorker1.RunWorkerAsync(test); } } /// <summary> /// The test class for our example. /// </summary> class TestObject { public int OneValue { get; set; } public int TwoValue { get; set; } }
DoWork 2. Place some code in DoWork. Then, use the DoWorkEventArgs in its body and as its result. We hook up the arguments and results from the RunWorkerAsync call.
Note The TestObject was passed to RunWorkerAsync, and that is received as e.Argument. We also have to cast.
/// <summary> /// Where we do the work in the program (the expensive slow stuff). /// </summary> private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { // // e.Argument contains whatever was sent to the background worker in RunWorkerAsync. // We can cast it to its original type. // TestObject argumentTest = e.Argument as TestObject; // // Boring.... // Thread.Sleep(10000); argumentTest.OneValue = 6; argumentTest.TwoValue = 3; // // Now, return the values we generated in this method. // ... Use e.Result. // e.Result = argumentTest; }
RunWorkerCompleted. You can use the RunWorkerCompleted event handler by clicking on the backgroundWorker1 icon in the tray. Now double-click in RunWorkerCompleted.
Next You will get some generated code that looks just like this. Put the argument receiving code in this method.
/// <summary> /// This is on the main thread, so we can update a TextBox or anything. /// </summary> private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // // Receive the result from DoWork, and display it. // TestObject test = e.Result as TestObject; this.Text = test.OneValue.ToString() + " " + test.TwoValue.ToString(); // // Will display "6 3" in title Text (in this example) // }
Review, steps. Call RunWorkerAsync with an argument. You can pass any argument to this method on BackgroundWorker, including null. It simply must inherit from object, which everything does.
Detail Your expensive code is executed in the DoWork method. Insert pause here as your program works.
Detail When your processing is done, RunWorkerCompleted is called. In this method, you receive the result.
ProgressBar. A ProgressBar visually displays progress. And the ProgressBar control in Windows Forms can be used with a BackgroundWorker.
A summary. We implemented the code for a BackgroundWorker control. We generally instead prefer ThreadPool when we need many threads. And threads are not always useful.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Apr 5, 2023 (simplify).
© 2007-2024 Sam Allen.