C # Explanation of BackgroundWorker,

Source: Internet
Author: User
Tags add time

C # Explanation of BackgroundWorker,

In C # programs, there are often some CPU-intensive operations that take a long time. If such operations are executed directly in the UI thread, the UI will not respond. The main way to solve these problems is to use multithreading to start a background thread and put the operation in this background thread. However, it is difficult to perform thread operations on native interfaces. It is difficult to complete inter-thread communication further.

Fortunately, the. NET Class Library provides a class called BackgroundWorker that can solve such problems elegantly. Although the BackgroundWorker class is relatively simple to use, there are still some details to pay attention to. Next we will introduce its main usage through the demo program. In the demo, we calculate the sum of 1 to 100. For demonstration, sleep is 600 milliseconds for each computation. The demo UI is:

Usage Overview

Create a BackgroundWorker instance on the form, add time-consuming operations to its DoWork event handler, and call its RunWorkerAsync method.

Private BackgroundWorker _ demoBGWorker = new BackgroundWorker (); _ demoBGWorker. doWork + = BGWorker_DoWork; _ demoBGWorker. runWorkerAsync (); private void BGWorker_DoWork (object sender, DoWorkEventArgs e) {// time-consuming calculation is executed here. Int sum = 0; for (int I = 0; I <= 100; I ++) {sum + = I ;}}

Is it a little too simple? Let's consider the following:

What should we do if we want to pass parameters to the operation process?
What should we do if we want to display real-time information on the UI during the operation?
What if we want to cancel the ongoing operation?
What should we do if an exception occurs during the operation?

Next we will solve these problems one by one.

Pass parameters to the operation process

It may be difficult to directly write 100 to the computation process. We plan to allow users to specify the sum range! Therefore, we need to pass 100 as a parameter to the computing process. In the overview, we call the RunWorkerAsync method to start the computing process. In fact, this method can accept an object-type parameter. With this, we can pass any data to the computing process:

// Do not forget to set the scroll bar. This. progressBarSum. maximum = 100; _ demoBGWorker. runWorkerAsync (100); // The following is the updated BGWorker_DoWork method: private void BGWorker_DoWork (object sender, DoWorkEventArgs e) {// The time-consuming operation is executed here. Int endNumber = 0; if (e. Argument! = Null) {endNumber = (int) e. argument;} int sum = 0; for (int I = 0; I <= endNumber; I ++) {sum + = I ;}}

The BGWorker_DoWork event processing function transmits the expected calculation information through the Argument attribute of parameter e.

Pass the message to the UI

Because of the long computing process, we want to display the current progress through the progress bar and display the intermediate computing results on the UI in real time. Of course, BackgroundWorker also provides good support for this case. It allows us to send messages to the UI thread during the execution of computing. Let's take a look at the specific practices below:

_demoBGWorker.WorkerReportsProgress = true;_demoBGWorker.ProgressChanged += BGWorker_ProgressChanged;

First, set the WorkerReportsProgress attribute to true, and then add a processing method for the ProgressChanged event:

Private void BGWorker_ProgressChanged (object sender, ProgressChangedEventArgs e) {// modify the display of the progress bar. This. progressBarSum. Value = e. ProgressPercentage; // if more information needs to be passed, you can use e. UserState to pass a custom type. // This is an object type object. You can pass any type through it. // We only return the current sum value through e. UserState and display it in the window. String message = e. UserState. ToString (); this. labelSum. Text = message ;}

Continue to update the BGWorker_DoWork method:

Private void BGWorker_DoWork (object sender, DoWorkEventArgs e) {BackgroundWorker bgWorker = sender as BackgroundWorker; int endNumber = 0; if (e. Argument! = Null) {endNumber = (int) e. argument;} int sum = 0; for (int I = 0; I <= endNumber; I ++) {sum + = I; string message = "Current sum is: "+ sum. toString (); // The ReportProgress method transmits the information to the ProcessChanged event handler. // The first parameter type is int, indicating the execution progress. // If more information needs to be transmitted, you can use the second parameter of ReportProgress. // Here we pass a message to the second parameter. BgWorker. ReportProgress (I, message); Thread. Sleep (600 );}}

OK. Now you can see updates to the progress bar and execution information.

Cancel operation

It is a basic design to allow the user to cancel the current operation during execution. BackgroundWorker naturally has good support:

_demoBGWorker.WorkerSupportsCancellation = true;

Like the WorkerReportsProgress attribute, if you want to support the cancel operation, you need to set the workersuppscanscancellation attribute to true. It is also supported in the BGWorker_DoWork method. In the for loop, add code after Thread. Sleep (600:

BgWorker. ReportProgress (I, message); Thread. Sleep (600); // check whether the current operation has been canceled during the operation. If (bgWorker. CancellationPending = true) {e. Cancel = true; break ;}

If the cancel button is detected, the current calculation process is exited. The following code is called when the cancel button is clicked:

_demoBGWorker.CancelAsync();

Now you can cancel the operation. Please try it!

Exception Handling

What should I do if an exception occurs during the computing process? Is there a way to know that the computing process is over? Of course, we need to get the computing results even if it ends normally.

_ DemoBGWorker. RunWorkerCompleted + = BGWorker_RunWorkerCompleted; private void BGWorker_RunWorkerCompleted (object sender, RunWorkerCompletedEventArgs e) {// close the window if the user cancels the current operation. If (e. Cancelled) {this. Close () ;}// the calculation has ended. You need to disable the cancel button. This. btnCancel. Enabled = false; // exceptions during calculation will be caught and can be processed here. If (e. Error! = Null) {Type errorType = e. error. getType (); switch (errorType. name) {case "ArgumentNullException": case "MyException": // do something. break; default: // do something. break;} // calculation result information: e. result // use it do something .}

The RunWorkerCompleted event processing function is called after the DoWork event processing function returns. You can perform operations after the operation, such as disabling the cancel button, exception handling, and result display.
Note: If you want to get e. Result, you need to set the e. Result attribute in the BGWorker_DoWork method, for example:

e.Result = sum;

 

To sum up, the BackgroundWorker class has complete functions and is easy to use. It is a powerful tool for processing asynchronous time-consuming operations!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.