The BackgroundWorker control. Displays the progress of completed work. Canceling the execution of a thread
This topic is a continuation of the topic:
Contents
- 1. Scheme for visualizing the progress of the completed work in the thread
- 2. Algorithm for visualizing the progress of completed work
- 3. Cancel execution of the thread. Scheme of interaction between event handlers
- 4. Sequence of actions (algorithm) for canceling the execution of a thread
- Related topics
Search other websites:
1. Scheme for visualizing the progress of the completed work in the thread
Figure 1 shows a diagram of the interaction between event handlers to display progress in the thread (background operation). On the basis of this scheme, an algorithm is described that describes the progress of the work performed (see section 2).
Figure 1. Visualization of the progress of completed work
⇑
2. Algorithm for visualizing the progress of completed work
To display the progress of the completed work (progress) in the thread, you need to use the following elements of the BackgroundWorker class:
- property WorkerReportProgress;
- method ReportProgress().
The sequence of actions for displaying the progress of a thread is as follows.
1. In design mode, set the property WorkerReportProgress = true.
2. In the DoWork event handler, call the ReportProgress method, in which you specify the percentage of work completed.
For example, if the thread runs a normal loop from 1 to 100, then the code for setting the percentage will be something like this:
// The event handler DoWork private void backgroundWorker1_DoWork(...) { // ... for (i = 1; i<=100; i++) { // Actions performed in a loop // ... // Call the handler for the ProgressChanged event try { backgroundWorker1.ReportProgress((i*100)/100); } catch(InvalidOperationException exception) { MessageBox.Show(exception.Message); } } }
where backgroundWorker1 is the name of the thread instance for which you want to display the task progress.
3. In the handler for the ProgressChanged event, display the percentage value in some visual component. The percentage value itself is derived from the e instance of the ProgressChangeEventArgs data class.
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { // Display percentage in label1.Text label1.Text = Convert.ToString(e.ProgressPercentage) + "%"; // Show percentage change in progressBar1.Value progressBar2.Value = e.ProgressPercentage; }
here
- label1 – a control that displays a percentage value (for example, 28%);
- ProgressChangeEventArgs – a class that represents data for the ProgressChanged event;
- e.ProgressPercentage – a property that returns an integer percentage that was generated in step 2 of the algorithm when the ReportProgress() method was called.
⇑
3. Cancel execution of the thread. Scheme of interaction between event handlers
When executing some thread (background operation), the user has the ability to cancel the execution of this thread. The BackgroundWorker class has all the necessary controls for canceling the execution of a thread. Figure 2 shows the interaction between the event handlers that are involved in canceling the execution of a thread.
Figure 2. Cancel execution of the thread. Interaction between event handlers
⇑
4. Sequence of actions (algorithm) for canceling the execution of a thread
It describes actions that need to be performed in order to correctly handle the cancellation of the execution of a thread (background operation). The following related members of the BackgroundWorker class are used to cancel a thread:
- property WorkerSupportsCancellation;
- method CancelAsync();
- property CancellationPending.
The algorithm that implements the correct cancellation of the execution of a thread is as follows.
1. Set the property WorkerSupportsCancellation = true. This will allow you to use the means of stopping (canceling) the thread.
2. Call the CancelAsync() method in the event handler of the click on the button to stop the thread
// Cancel the thread execution private void button2_Click(object sender, EventArgs e) { try { backgroundWorker1.CancelAsync(); } catch(InvalidOperationException exception) { // Display the error message MessageBox.Show(exception.Message); } }
Now, when you click on the button to stop the thread, a corresponding request will be generated in the DoWork event handler.
3. In the DoWork event handler, check whether the command to stop the thread has been invoked. This is accomplished by checking the CancellationPending property.
In the simplest case, for a normal loop, the thread stopping code will look like this:
... private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { ... // Thread execution loop for (int i=0; i<1000; i++) { ... // Checking if a thread cancellation command has been executed if (backgroundWorker1.CancellationPending) break; // if there was a request to stop the thread, then exit the loop } } ...
4. In the handler for the RunWorkerCompleted event, take the appropriate action after the thread finishes executing.
In order to recognize the way the stream ends, you can enter an additional internal variable that will take on the appropriate value. The following code introduces an internal variable fCancelled into the form class. This variable determines whether the thread was canceled by the user and whether it is raised in the DoWork event handler. The event handler text is as follows.
The result of the completion of the thread execution (normal completion or canceled by the user) is displayed in the handler for the RunWorkerCompleted event. Also in this handler, the fCancelled variable is set to its original state.
// Form class public partial class Form1 : Form { // Determines how the thread was terminated bool fCancelled = false; // if fCancelled = false, then the thread execution was canceled by the user ... // Thread execution - DoWork event handler - sets fCancelled value private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { ... // Thread execution loop for (int i=0; i<1000; i++) { ... // Checking if a thread cancellation command has been executed if (backgroundWorker1.CancellationPending) { // indicate that the thread execution was canceled by the user fCancelled = true; // end the thread, exit the loop break; } } } // Thread termination event handler private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // Checking how the thread was terminated if (fCancelled) label1.Text = "The thread was cancelled"; else label1.Text = "The thread was completed normally"; // Return fCancelled to its initial value fCancelled = false; } ... }
⇑
Related topics
- Control (component) BackgroundWorker. Working with threads, background operations. Overview of methods, properties, events
- Development of a program for demonstrating work for threads with execution. BackgroundWorker control. Sorting an array by insertion, bubble, selection algorithms
⇑