C # backgroundworker details, legends, and Principle Analysis

Source: Internet
Author: User

Http://hi.baidu.com/jiang_yy_jiang/blog/item/c96c4826299fce008b82a126.html

 

I declare that most of the materials have been sorted out by referring to the Internet.

1.

Added the backgroundworker component in Vs, which is very convenient to use in multi-threaded programming. However, at the beginning, it took a lot of detours because it was not clear about its usage mechanism, now I will share with you my experience in using it.
This attribute, method, and event are mainly used in the backgroundworker class:
Important attributes:
1. cancellationpending gets a value indicating whether the application has requested to cancel background operations. By judging the cancellationpending attribute in the dowork event, you can determine whether the background operation needs to be canceled (that is, the end thread );
2. isbusy gets a value indicating whether the backgroundworker is running an asynchronous operation. The isbusy attribute is used in the program to determine whether background operations are in use;
3. workerreportsprogress gets or sets a value that indicates whether the backgroundworker can report progress updates.
4. workersuppscanscancellation gets or sets a value that indicates whether backgroundworker supports asynchronous cancellation. Set workersuppscanscancellation to true so that the program can call the cancelasync method to submit a request to terminate the suspended background operation;
Important methods:
1. cancelasync requests to cancel pending background operations
2. runworkerasync starts to perform background operations.
3. reportprogress raises the progresschanged event.
Important events:
1. occurs when dowork calls runworkerasync.
2. progresschanged when reportprogress is called
3. runworkercompleted occurs when the background operation is completed, canceled, or exception is thrown.
There are also three important parameters: runworkercompletedeventargs, doworkeventargs, and progresschangedeventargs.
The Calling mechanism and sequence of attributes, methods, and events of backgroundworker:

It can be seen that three important parameter transfer processes occurred throughout the life cycle:
Parameter Pass 1: This Parameter Pass is to pass the object in runworkerasync (object) to the doworkeventargs of the dowork event. argument, because only one parameter can be passed here, in actual application, encapsulate a class, and pass the entire instantiated class as the object of runworkerasync to doworkeventargs. argument;
Parameter transfer 2: This is to pass the program running progress to the progresschanged event. In actual use, it is often used to update the progress bar or log information for methods and events;
Parameter transfer 3: Before the dowork event ends, the result data generated by the background thread is assigned to doworkeventargs. result, while calling the runworkercompleted event runworkercompletedeventargs. Result attribute in the runworkercompleted event to obtain the result generated by the background thread.
In addition, we can see that the dowork event is run in the background thread, so the user interface content cannot be operated in this event. If you need to update the user interface, you can use the progresschanged event and runworkcompleted event.

After understanding the event calling sequence and parameter passing mechanism of bagkgroundworker, it is much easier to use this component for multithreaded programming. Detailed examples can be found in my Offline Browser.

2.

If a winform application executes a very lengthy processing operation (such as file query), it locks the user interface during execution, although the main activity window is always running, however, users cannot interact with the program, move the form, or change the size of the form. How can this program respond. The answer is to execute this operation in the background thread.
There are several ways to do this:
(1) Delegated asynchronous call
Use a specific time-consuming operation as a delegate and use begininvoke to asynchronously execute this delegate (invoke is a synchronous call). You can also input parameters for this operation and obtain the return value through the endinvoke method.
(2) Use threadpool
Create a self-contained waitcallback delegate in the. NET Framework and put it in the thread pool to run threadpool. queueuserworkitem (callback). According to the definition of the waitcallback delegate, You can input an object-type parameter.
However, you cannot precisely control the threads in the thread pool.
(3) Use thread
Compared with threadpool, thread overhead is relatively large. However, it has its advantages. The Thread class can be used to explicitly manage threads. Use the threadpool class to create a thread whenever possible. However, in some cases, you still need to create and manage your own threads, rather than using the threadpool class. In. NET 2.0, a new delegate parameterizedthreadstart is provided to support starting a thread and passing in parameters. This is an improvement for the original threadstart delegate.

After talking about this, I haven't mentioned today's main character backgroundworker. He is also a new class added in 2.0, which can be used to start the background thread and call the main thread method after the background computing ends. it can be seen that the same function can also be implemented using a delegated asynchronous call, but using backgroundworker makes it easier and faster, saving development time, it also saves you from creating your own delegate and calling them. Is that true? Let's look at the example below. In fact, I also see the example from 101samples.
Let's take a look at the main concepts in backgroundworker.

1. Main events and parameters.
Dowork -- this event is triggered when the backgroundworker. runworkerasync method is executed and the doworkeventargs parameter is passed;
Progresschanged -- Changes in processing status obtained during Operation processing. This event is triggered by using the backgroundworker. reportprogress (INT) method, and the progresschangedeventargs is passed, which includes the percentage of processing;

Runworkercompleted -- this event is triggered after the asynchronous operation is complete. Of course, if you need to end the operation, you can execute backgroundworker. the cancelasync method must be called asynchronously and check backgroundworker In the asynchronous delegate operation. if the cancellationpending attribute is true, the asynchronous call is called and the doworkeventargs. the cancel attribute is set to true, so that when you exit the asynchronous call, you can let the function that handles the runworkercompleted event know whether to exit normally or midway through.

Second: the main method.
Backgroundworker. runworkerasync --
The method of "starting" Asynchronous call has two reloads: runworkerasync () and runworkerasync (Object argument). The second overload provides a parameter for asynchronous call. (If multiple parameters need to be passed, use a class to pass them ). After this method is called, The dowork event is triggered, and the doworkeventarg event parameter of the function for processing the dowork event contains the parameters passed by runworkerasync. You can perform complex operations in the corresponding dowork processing functions.
Backgroundworker. reportprogress --
Sometimes you need to constantly report the progress to the user in a lengthy operation, so that you can call reportprogress (INT percent) and trigger the progresschanged event when calling the reportprogress method. Provides an integer between 0 and 100, which indicates the percentage of background activities completed. You may also provide any object as the second parameter, allowing you to pass status information to the event handler. As the progresschangedeventargs parameter attribute passed to this process, the percentage and your own object (if provided) will be passed to progresschanged
Event Handler. These attributes are named progresspercentage and userstate respectively, and your event handler can use them in any way you need. (Note: This method is only available when the backgroundworker. workerreportsprogress attribute is set to true ).
Backgroundworker. cancelasync --
But this method is called when you need to exit the asynchronous call. However, this is not enough because it only sets the backgroudworker. cancellationpending attribute to true. You need to constantly check whether backgroudworker. cancellationpending is true during asynchronous call processing. If it is true, exit. (Note: This method is only available when the backgroundworker. workersuppscanscancellation attribute is set to true ).

Paste the code in samples and you will understand it:

Public partial
Class mainform: Form
{
Private system. componentmodel. backgroundworker backgroundcalculator;

Public mainform ()
{
Initializecomponent ();
Backgroundcalculator = new backgroundworker ();
Backgroundcalculator. workerreportsprogress = true;
Backgroundcalculator. workersuppscanscancellation = true;
Backgroundcalculator. dowork + =
New doworkeventhandler (backgroundcalculator_dowork );
Backgroundcalculator. progresschanged + =
New progresschangedeventhandler (backgroundcalculator_progresschanged );
Backgroundcalculator. runworkercompleted + =
New runworkercompletedeventhandler (backgroundcalculator_runworkercompleted );
Updatestatus (string. Empty );
}

Privateint getnextprimeasync (INT start, backgroundworker worker, doworkeventargs E)
{
Int percentcomplete
= 0;

Start ++;
While (! Isprime (start ))
{
// Check for cancellation
If (worker. cancellationpending)
{
E. Cancel = true;
Break;
}
Else
{
Start ++;
Percentcomplete ++;

Worker. reportprogress (percentcomplete % 100 );
}
}
Return start;
}

Void backgroundcalculator_runworkercompleted (Object sender, runworkercompletedeventargs E)
{
If (E. cancelled)
{
Updatestatus ("cancelled .");
}
Elseif (E. Error
! = NULL)
{
Reporterror (E. Error );
}
Else
{
Reportprime (INT) E. Result );
}
Calcprogress. value = 0;
}

Void backgroundcalculator_progresschanged (Object sender, progresschangedeventargs E)
{
Updateprogress (E. progresspercentage );
}
Void backgroundcalculator_dowork (Object sender, doworkeventargs E)
{
Int start
= (INT) E. argument;
E. Result = getnextprimeasync (START, (backgroundworker) sender, e );
}

Privatevoid nextprimeasyncbutton_click (Object sender, eventargs E)
{
Updatestatus ("calculating ...");

Int start;
Int32.tryparse (textboxprime. Text, out start );

If (start
= 0)
{
Reporterror ("the number must be a valid integer ");
}
Else
{
// Kick off the background Worker Process
Backgroundcalculator. runworkerasync (Int. parse (textboxprime. Text ));
}
}

Privatevoid cancelbutton_click (Object sender, eventargs E)
{
If (backgroundcalculator. isbusy)
{
Updatestatus ("cancelling ...");
Backgroundcalculator. cancelasync ();
}
}

// Update the status label
Privatevoid updatestatus (string status)
{
Calcstatus. Text = status;
}

// Indicate progress using progress bar
Privatevoid updateprogress (INT percentcomplete)
{
Calcprogress. value = percentcomplete;
}
}

The backgroundworker creates its own delegate and calls the invoke method of the form to run it. The backgroundworker component handles the thread conversion in an elegant way. The backgroundworker component allows you to call its reportprogress method from the background thread. This method triggers its progresschanged event processing routine to return to the form thread. Instead of using the Delegate/invoke method to handle the thread conversion, you call reportprogress and the other tasks are handed over to the component.

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.