Progress Bar, Multithread in WPF using C#

I created a video a while ago that discussed how to implement a progress bar in a windows form application. It used the System.Thread class library and the the BackgroundWorker class. With the release of .NET 4, there is a new. easier way to implement this.

image

In this example, I have added the progress bar to the status bar and a start button in the WPF XAML code.

<Grid>
   <Button Content="Start" Height="23"
           Click="buttonStart_Click"
           HorizontalAlignment="Right"
           Margin="0,15,15,0"
           Name="buttonStart"
           VerticalAlignment="Top"
           Width="75" />
   <StatusBar Name="StatusBar1"
              VerticalAlignment="Bottom"
              Background="Black"
              Margin="0,0,0,0" />
</Grid>

To add a progress bar to the status bar, I add the following code to the buttonStart_Click method in the code-behind.

ProgressBar progressBar = new ProgressBar();
progressBar.IsIndeterminate = false;
progressBar.Orientation = Orientation.Horizontal;
progressBar.Width = 419;
progressBar.Height = 20;
 
Duration duration = new Duration(TimeSpan.FromSeconds((30)));
DoubleAnimation doubleAnimatiion = new DoubleAnimation(200, duration);
StatusBar1.Items.Add(progressBar);

I should make a comment about setting the duration. You would want the progress bar to complete in about the same time the code you program runs completes. This is very specific to what you program is doing. One example I can give is perhaps your program will process a number of files in a directory. Calculate that it will take about 2 seconds per file to process. Then multiply that number by about 20 – 30% to give you additional time, just in case some files were big. This could give you a ball park figure of the TimeSpan you need to set.

In order the get a smooth running progress bar, you need to code it to run on a different thread than the thread which is performing your actual work. I do this by using the Task namespace from the Task Parallel Library which was newly released with .NET 4.

Action MainThreadDoWork = new Action(() =>
{
   //add thread safe code here.
   //Confirm thread will not use GUI thread
   System.Threading.Thread.Sleep(20000);
});

The second thread will start my progress bar.

Action ExecuteProgressBar = new Action(() =>
{
   progress.BeginAnimation(ProgressBar.ValueProperty, doubleAnimatiion);
});

The third thread will wait for the first thread to complete and then re-enable the start button and hide the progress bar.

Action FinalThreadDoWOrk = new Action(() =>
{
   buttonStart.IsEnabled = true;
   StatusBar1.Items.Remove(progress);
});

Lastly, I use the Task class to start the threads.

Task MainThreadDoWorkTask =
      Task.Factory.StartNew(() => MainThreadDoWork());
Task ExecuteProgressBarTask = new Task(ExecuteProgressBar);
ExecuteProgressBarTask.RunSynchronously();
MainThreadDoWorkTask.ContinueWith(t => FinalThreadDoWOrk(), uiThread);

Even though, it is possible to do the same with a BackgroundWorker thread, this is the new approach provided in .NET 4. It is always a good idea and necessary to stay current.

Download the source