In this video, we will discuss the use of BackgroundWorker Class in windows forms application with an example. Along the way, we will also discuss using progressbar control.
First, let's understand, why should we use BackgroundWorker Class?
By default windows applications are single threaded. This means, when we run the application there will be a single thread which is commonly called as UI thread. This is the thread that is responsible for doing all the work, that is
1. Creating and updating user interface elements and
2. Executing application code
For example, let's say we have a function that takes 10 seconds to complete. While the UI thread is busy processing this function, the UI of the application is frozen and the end user cannot interact with the controls on the form during those 10 seconds. To keep our application responsive, we can create a new Thread ourselves and then ask that thread to execute the function that takes long time to complete, so that the UI thread is free to update the controls on the form. But the problem with creating threads ourselves is that, it can get extremely complex especially when we have to update UI controls based on the status of the thread function execution. It's dangerous to access UI objects on a thread that didn't create them. So the better option here is to use, BackgroundWorker Class which simplifies multithreading.
Using BackgroundWorker Class
Create a new windows forms application and design the form as shown below.
The windows form contains
a) Two Buttons
b) Progressbar control
c) Label control
Now, drag and drop BackgroundWorker object from toolbox onto the form.
On Button1 set the following properties
Name = btnProcess
Text = Process
On Button2 set the following properties
Name = btnCancel
Text = Cancel
Properties of BackgroundWorker class
WorkerSupportsCancellation - Set this property to true if you want the background operation to allow cancellation.
WorkerReportsProgress - Set this property to true if you want the background operation to report progress.
Events of BackgroundWorker class
DoWork - The DoWork event handler is where the time consuming operation runs on the background thread.
ProgressChanged - The ProgressChanged event handler is where we write code to update the user interface elements with the progress made so far.
RunWorkerCompleted - This event gets raised for 3 reasons
a) When the background worker has completed processing successfully
b) When the background worker encountered an error
c) When the background worker is requested to cancel the execution
First, let's understand, why should we use BackgroundWorker Class?
By default windows applications are single threaded. This means, when we run the application there will be a single thread which is commonly called as UI thread. This is the thread that is responsible for doing all the work, that is
1. Creating and updating user interface elements and
2. Executing application code
For example, let's say we have a function that takes 10 seconds to complete. While the UI thread is busy processing this function, the UI of the application is frozen and the end user cannot interact with the controls on the form during those 10 seconds. To keep our application responsive, we can create a new Thread ourselves and then ask that thread to execute the function that takes long time to complete, so that the UI thread is free to update the controls on the form. But the problem with creating threads ourselves is that, it can get extremely complex especially when we have to update UI controls based on the status of the thread function execution. It's dangerous to access UI objects on a thread that didn't create them. So the better option here is to use, BackgroundWorker Class which simplifies multithreading.
Using BackgroundWorker Class
Create a new windows forms application and design the form as shown below.
The windows form contains
a) Two Buttons
b) Progressbar control
c) Label control
Now, drag and drop BackgroundWorker object from toolbox onto the form.
On Button1 set the following properties
Name = btnProcess
Text = Process
On Button2 set the following properties
Name = btnCancel
Text = Cancel
Properties of BackgroundWorker class
WorkerSupportsCancellation - Set this property to true if you want the background operation to allow cancellation.
WorkerReportsProgress - Set this property to true if you want the background operation to report progress.
Events of BackgroundWorker class
DoWork - The DoWork event handler is where the time consuming operation runs on the background thread.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs
e)
{
int sum = 0;
for (int i =
1; i <= 100; i++)
{
Thread.Sleep(100);
sum = sum + i;
// Calling ReportProgress() method raises
ProgressChanged event
// To this method pass the percentage of
processing that is complete
backgroundWorker1.ReportProgress(i);
// Check if the cancellation is requested
if (backgroundWorker1.CancellationPending)
{
// Set Cancel property of
DoWorkEventArgs object to true
e.Cancel = true;
// Reset progress percentage to ZERO
and return
backgroundWorker1.ReportProgress(0);
return;
}
}
// Store the result in Result property of
DoWorkEventArgs object
e.Result = sum;
}
ProgressChanged - The ProgressChanged event handler is where we write code to update the user interface elements with the progress made so far.
private void backgroundWorker1_ProgressChanged
(object sender, ProgressChangedEventArgs
e)
{
progressBar1.Value = e.ProgressPercentage;
label1.Text = e.ProgressPercentage.ToString()
+ "%";
}
RunWorkerCompleted - This event gets raised for 3 reasons
a) When the background worker has completed processing successfully
b) When the background worker encountered an error
c) When the background worker is requested to cancel the execution
private void backgroundWorker1_RunWorkerCompleted
(object sender, RunWorkerCompletedEventArgs
e)
{
if (e.Cancelled)
{
label1.Text = "Processing
cancelled";
}
else if (e.Error
!= null)
{
label1.Text = e.Error.Message;
}
else
{
label1.Text = e.Result.ToString();
}
}
private void btnProcess_Click(object sender, EventArgs
e)
{
// Check if the backgroundWorker is already
busy running the asynchronous operation
if (!backgroundWorker1.IsBusy)
{
// This method will start the execution
asynchronously in the background
backgroundWorker1.RunWorkerAsync();
}
}
private void btnCancel_Click(object sender, EventArgs
e)
{
if (backgroundWorker1.IsBusy)
{
// Cancel the asynchronous operation if still
in progress
backgroundWorker1.CancelAsync();
}
}
please provide wpf tutorilas......
ReplyDeleteHy dear vankat thank you so much, that you have start to windows programing now is it start to wpf?
ReplyDeleteNice....
ReplyDeleteCan we do the same in python.
Thank you very much for making it easy to understand.
ReplyDeletewhat if the "backgroundWorker1_DoWork" executes external proces.exe files?
ReplyDeleteI mean instead of adding a number using for loop,backgroundWorker1_DoWork
start the process by invoking exe file originally created by other programming language? how we can report workdone?Thank you