Abstract: This paper introduces the functions of the backgroundworker component and its application in event-based Asynchronous Operation Programming, and briefly introduces the implementation principle of the component.
OverviewIn an application, you may encounter some time-consuming functional operations, such as data downloading, complex computing, and database transactions. Generally, such functions are implemented on separate threads, after the execution is completed, the result is displayed on the user interface. This prevents the user interface from responding for a long time. In. NET 2.0 and later versions, FCL provides the backgroundworker component to conveniently implement these functional requirements.
Component IntroductionThe backgroundworker class is located in the namespace of system. componentmodel. It executes operations on individual threads to implement event-based asynchronous mode. The following describes the main members of the backgroundworker class.
Runworkerasync starts asynchronous operations
The 1st main method of the backgroundworker class is runworkerasync, which submits a request to start the operation asynchronously. After a request is sent, a dowork event is triggered, run the asynchronous operation code in the event handler. Runworkerasync
The method signature is as follows:
public void RunWorkerAsync();public void RunWorkerAsync(Object argument);
If an asynchronous operation requires an operation parameter, it can be provided as an argument parameter. Because the parameter type is object, type conversion may be required during access.
Cancelasync cancels asynchronous operations
The cancelasync method submits a request to terminate the asynchronous operation and sets the cancellationpending attribute to true. It should be noted that whether the cancelasync method is successfully called is related to the workersuppscanscancellation attribute. If asynchronous operations can be canceled, set the workersuppscanscancellation attribute to true. Otherwise, an exception is thrown when you call this method. The cancelasync method does not contain parameters. The method signature is as follows:
public void CancelAsync();
When the cancelasync method is called, the value of the cancellationpending attribute of backgroundworker is set to true. Therefore, when writing a helper method executed in a separate thread, the Code should regularly check the cancellationpending attribute, check whether this attribute has been set to true. If it is true, the execution of the auxiliary method should be ended.
// Cancel if (bgw. cancellationpending) {e. Cancel = true; break ;}
One thing to note is that the Code in the dowork event handler may have completed processing when the cancellation request is sent. Therefore, dowork event handlers or helper methods may miss the time to set the cancellationpending attribute to true. In this case, even if the cancelasync method is called to cancel the Asynchronous Operation Request, the cancelled flag of the runworkercompletedeventargs parameter in the runworkercompleted event handler will not be set to true, this is a race condition problem that often occurs in multi-threaded programming. Therefore, you need to consider it when writing code.
Reportprogress report progress
The backgroundworker class provides
The reportprogress method. If you call this method, the progresschanged event is triggered. You can register this event to obtain the asynchronous execution progress information in the event handler. The method signature is as follows:
public void ReportProgress(int percentProgress);public void ReportProgress(int percentProgress,Object userState);
This method contains two versions. percentprogress indicates the progress percentage. The value ranges from 0 to 100, and userstate indicates the Custom User status. Like the cancelasync method, when the workerreportsprogress attribute of backgroundworker is set to true, the reportprogress method is called successfully. Otherwise, an invalidoperationexception occurs.
Isbusy running status
Isbusy running status. The signature is as follows:
publicbool IsBusy { get; }
This attribute is used to query whether the backgroundworker instance is running an asynchronous operation. If the backgroundworker is running an asynchronous operation, the value is true. Otherwise, the value is false.
BackgroundworkerClass 3 events
The dowork event handler is used to call an auxiliary method for actual processing. Because the event handler is executed on a thread different from the UI, therefore, make sure that no user interface objects are operated in the dowork event handler. If the auxiliary method requires parameter support, you can pass in the runworkerasync method.
In the dowork event handler, this parameter is extracted using the doworkeventargs. Argument attribute.
During the asynchronous operation, you can use the progresschanged event handler to obtain the asynchronous operation progress information and use the runworkercompleted event handler to obtain the asynchronous operation result information, you can securely communicate with the user interface in the event handlers of progresschanged and runworkercompleted.
Backgroundworker bgw = new backgroundworker (); Public A () {bgw. workersuppscanscancellation = true; bgw.WorkerReportsProgress = true;
Bgw. progresschanged + = new progresschangedeventhandler (bgw_progresschanged );
Bgw. runworkercompleted + = new runworkercompletedeventhandler (bgw_runworkercompleted );
Bgw. dowork + = new doworkeventhandler (bgw_dowork); bgw. runworkerasync ();}
Void bgw_dowork (Object sender, doworkeventargs e) {// For (INT I = 0; I <100; I ++) {// cancel if (bgw. cancellationpending) {e. cancel = true; break;} bgw. reportprogress (I + 1 );}}
Progresschanged progress
Void bgw_progresschanged (Object sender, progresschangedeventargs e) {// update the progress bar this. progressbar1.value = E. progresspercentage ;}
Void bgw_runworkercompleted (Object sender, runworkercompletedeventargs e) {// jump to the end page // cancel if (E. cancelled) {// ask whether to cancel} // If (E. error! = NULL) {MessageBox. Show (E. Error. Message) ;}// processing after normal completion}