C # BackgroundWorker Detailed

Source: Internet
Author: User

In C # programs, there are often time-consuming CPU-intensive operations, which can occur if the UI does not respond directly to this operation. The main way to solve this type of problem is to use multi-threading, start a background thread, and put the operation on the background thread. However, the threading of the native interface is difficult, and it can be difficult to further complete the communication between threads.

Fortunately, the. NET Class Library provides a class called BackgroundWorker that can be used to solve such problems gracefully. Although the BackgroundWorker class is relatively simple to use, there are some details that need to be noticed, and the main usage of the demo program is described below. We calculate the sum of 1 to 100 in the demo and, for demonstration, sleep 600 milliseconds for each calculation, the demo UI is:

Usage overview

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

Private BackgroundWorker _demobgworker = new BackgroundWorker (); _demobgworker.dowork + = Bgworker_dowork;_ Demobgworker.runworkerasync ();p rivate void Bgworker_dowork (object sender, DoWorkEventArgs e) {    //Perform time-consuming operations here.    int sum = 0;    for (int i = 0; I <=; i++)    {        sum + = i;    }}

Isn't it a little too simple? So let's consider the following question:

What if we want to pass the arguments to the operation procedure?
What do we do when we want to display real-time information on the UI during the operation?
What if we want to cancel an operation that is in progress?
What should we do if the operation is abnormal?

Next we will deal with these problems one after the other.

Pass parameters to the operation process

It is not good to write the 100 directly to the operation, we also intend to allow the user to specify the scope of the sum! So we need to pass 100 as a parameter to the calculation process. In the overview we start the calculation process by calling the RunWorkerAsync method, in fact, this method can accept a parameter of type object. With it we can pass any data to the computational process:

Don't 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) {    //Perform time-consuming operations 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 handler functions through the argument property of the parameter E to the information we expect.

Passing messages to the UI

Due to the long calculation process, we also want to display the calculated intermediate results on the UI in real time, while showing the current progress through the progress bar. Of course, BackgroundWorker also provides a good support for this use case. It allows us to send a message to the UI thread during the execution of the calculation, and take a look at the specific approach:

_demobgworker.workerreportsprogress = true;_demobgworker.progresschanged + = bgworker_progresschanged;

First, set the Workerreportsprogress property 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 you have more information to pass, you can use E.userstate to pass a custom type.    //This is an object of type objects that you can pass any type through.    //We only pass the value of the current sum back through e.userstate and display it on the window.    String message = E.userstate.tostring ();    This.labelSum.Text = message;}

To continue updating 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 passes the information to the Processchanged event handler function.        //The first parameter type is int, which indicates the progress of the execution.        //If there is more information to pass, you can use the second parameter of ReportProgress.        //Here we pass in a message to the second parameter.        bgworker.reportprogress (i, message);        Thread.Sleep (+);    }}

OK, now you can see the progress bar and the update of the execution information.

Cancel operation

Allowing the user to cancel the current operation during execution is a basic design, BackgroundWorker naturally has very good support:

_demobgworker.workersupportscancellation = true;

As with the Workerreportsprogress property, we need to set the Workersupportscancellation property to True if you want to support the cancel operation. and also to support in the Bgworker_dowork method, add code after thread.sleep (600) in the For loop:

Bgworker.reportprogress (i, message); Thread.Sleep (600);//In the process of operation, you need to check whether the user canceled the current operation. if (bgworker.cancellationpending = = True) {    E.cancel = true;    break;}

If the Cancel button that the user clicked is detected, the current calculation process is exited. Here is the code to invoke when the Cancel button is clicked:

_demobgworker.cancelasync ();

Now you can support cancel operation, try it quickly!

Exception handling

What happens if an exception occurs during the calculation? Is there a way to know that the calculation process is over? Of course, even the normal end needs to get the results of the calculations.

_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 and the Cancel button needs to be disabled.    this.btnCancel.Enabled = false;    Exceptions in the calculation process are caught and can be handled 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 handler function is called after the DoWork event handler returns. Through it we can do some operations after the end of the operation, such as disabling the Cancel button, exception handling, results display and so on.
Note that if you want to get e.result, you need to set the E.result property in the Bgworker_dowork method, such as:

E.result = sum;

Summary, the BackgroundWorker class function is perfect and easy to use, it is a weapon to deal with asynchronous time-consuming operation!

C # BackgroundWorker Detailed

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.