Wednesday, November 10, 2010

Use BackgroundWorker (3)

In this artile, I am going to build a simple application which has a button which is to call the calculuation function in background. A progressbar which will show the background progress status. A cancel button which will cancel the background thread working.

We can build this application use Asp.net web application or Window form application or WPF application. As for asp.net there is no default progressbar control in visual studio tool box, there need us to create custom web control in order to show progressbar. So I am going to test use either Winform or WPF application.

For windows form application there is BackgroundWorker control in tool box, so I am going to demostrate how to use this control.

1. Create a winform application.
2. Drag the progressbar control, buttons. And BackgroundWorker control to the form. Like below:


I. Build Progress Bar showing the background calculation progress


In the code behind, after initialize the component, we set the status bar Min/Max values, and the backgroundworker support progressreport and support cancelling property.

backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;

progressBar1.Minimum=0;
progressBar1.Maximum=100;

In the designer, right click the Background control in the properties events window:
Double click the DoWork, ProgressChanged, RunWorkerCompleted. See the following picture:



In the code behind create the following code:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}

Double click Button1, and generate code:
private void button1_Click(object sender, EventArgs e)
{
}
We add the line of the code to call the background thread working:
backgroundWorker1.RunWorkerAsync();

Let's add the following code in the above backgroundWorker1_DoWork method:

for (int i = 0; i <= 10; i++)
{
backgroundWorker1.ReportProgress(i*10);
Thread.Sleep(500);
}

And the code progressBar1.Value=e.ProgressPercentage; to backgroundWorker1_ProgressChanged. Add the code MessageBox.Show("Congradulations, Calculation Finished!"); to backgroundWorker1_RunWorkerCompleted method.

Now the code behind will be:


public partial class BackgroundWorkerExample : Form
{
public BackgroundWorkerExample()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;

progressBar1.Minimum = 0;
progressBar1.Maximum = 100;
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 10; i++)
{
backgroundWorker1.ReportProgress(i * 10);
Thread.Sleep(500);
}
}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Congradulations, Calculation Finished!");
}

private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
}

When we compile this solution, our application support the status update on the background calculation. After calculation is done, there is a message box jump out saying "Congradulations, Calculation Finished!".

The running result is like the following picture:




II. Let the application support Async Cancellation


Double click the Button2 and create code behind:
private void button2_Click(object sender, EventArgs e)
{
}
Add the code backgroundWorker1.CancelAsync(); in the above block.


Change the code in backgroundWorker1_DoWork block to be:


for (int i = 0; i <= 10; i++)
{
if (backgroundWorker1.CancellationPending == true)
{
MessageBox.Show("Calculation Canceled!");
e.Cancel = true;
return;
}
backgroundWorker1.ReportProgress(i*10);
Thread.Sleep(500);
}

And change the code in backgroundWorker1_RunWorkerCompleted block to be:

if (!(e.Cancelled))
MessageBox.Show("Congradulations, Calculation Finished!");
else
MessageBox.Show("Due to Cancellation, Calculation isn't finished");

Rebuilt our solution, now our project support Async Cancellation. Like the picture below:



You can download my code at:

http://groups.google.com/group/jiezhu0815myfiles/web/WinformBackgroundWorkerReportProgress.rar

No comments: