Click here to Skip to main content
Click here to Skip to main content

Working with BackgroundWorker & Creating Your Own Loading Class

, 5 Mar 2009
Rate this:
Please Sign up or sign in to vote.
Basic knowledge about BackgroundWorker. Using BackgroundWorker to create a loading form to inform the user that the application is still working fine. From that, create your own loading class to automate this progress and make the code and the form reusable.

Background

It's always annoying when I run an application, click a button and the whole application becomes frozen. You don't know whether it has crashed or it is still working. Try to click on any other button, we will get the message "Not responding" or something like that.

image01.jpg

That does not sound like a modern application, doesn't it. So don't make your application like that. Whenever your application starts to run a big slow method, make sure you inform your user about that.

Using the Code

BackgroundWorker is there to help you solve this problem. With this, you don't need to worry about how Asynchronous methods work. To inform users that your application is running, create a Loading Form, run the BackgroundWorker, show up the Loading Form. Whenever the backgroundworker is completed, close the form.

image02.jpg

Simple right? But I want more. For me, reusable is also important. I need to use Loading Form in different applications, different form. I can't be asked to create a backgroundworker for every form, every function for which I need it.

So I also create my own Class/Library to make my life easier. This class will auto-create a backgroundworker, run the code, show the form, and close the form when it finishes. This is one of my favorite classes in my Utilities Belt Library. (I have my utilities class which I use for almost every project that I am working on, can't live without it.)

If you don't know about the basic BackgroundWorker, you should read the "Basic BackgroundWorker" part. If you just want to know more about how I create my class, scroll down to the "Make your own class" part.

Basic BackgroundWorker

BackgroundWorker is a simple (simplest maybe) way to make your app run multi-threading. To using it:

Insert a new BackgroundWorker into your form.

Insert your function into DoWork event.

private void bWorker1_DoWork(object sender, DoWorkEventArgs e)  
{  
    decimal ThisMaxValue = Maximum;  
    if(e.Argument!=null && e.Argument is decimal)  
        ThisMaxValue = (decimal)e.Argument;  
    //This is run in a new thread  
    for (int i = 0; i <= ThisMaxValue; i++)  
    {  
        Idx = i;  
    }  
}

[Optional] Insert some command into RunWorkerCompleted if needed.

private void bWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)  
{  
    nudShowResult.Value = Idx;  
    timer1.Stop();  
    if (LoadingForm != null && LoadingForm.Visible)  
        LoadingForm.Dispose();  
}

Start running BackgroundWorker.

private void button4_Click(object sender, EventArgs e)   
{   
    timer1.Start();   
    bWorker1.RunWorkerAsync();   
    LoadingForm = new FrmLoading();   
    LoadingForm.ShowDialog();   
}

Make sure to show the form after running the backgroundworker. If not, the backgroundworker won't run ask if it needs to wait for the form to close first.

Create a timer if you need to update the value into a control:

private void timer1_Tick(object sender, EventArgs e)   
{   
    nudShowResult.Value = Idx;   
}

The function in BackgroundWorker is not allowed to access any controls because it is in a different thread. If it fails to do so, you will get a really slow error report. So make sure you don't point to any control in the DoWork event.

To run BackgroundWorker function with an argument, you could do like this:

bWorker1.RunWorkerAsync(decimal.Parse(textBox1.Text));

Then extract the argument from eventArgs:

if(e.Argument!=null && e.Argument is decimal)   
    ThisMaxValue = (decimal)e.Argument;

You could check my code file for more details if necessary.

Make your Own Class

This class isn't exactly what in my Utilities belts class. This is made for the purpose of this tutorial only.

So what we need:

Create a new Library project and add System.Windows.Form into your project references.

Add those using into your class file:

using System.Windows.Forms;   
using System.ComponentModel;

Add a new form for loading form. It will show up every time the BackgroundWorker starts and close when it finishes.

Declare a delegate void. Use this to pass a function into your class:

public BackgroundWorker Bw;   
public delegate void RunFunction();

Add some variables for the class:

public BackgroundWorker Bw;   
public RunFunction thisFunction;   
LoadingForm newLoading;

The construction will be like this:

public BackgroundLoading(RunFunction newFunction)   
{   
    thisFunction = newFunction;   
    Bw = new BackgroundWorker();   
    Bw.DoWork += new DoWorkEventHandler(Bw_DoWork);   
    Bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Bw_RunWorkerCompleted);
}

newFunction is what will run in DoWork event. Create a new BackgroundWork and add an event handler for it.

The basic simple code for those event handlers is:

void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)   
{   
    newLoading.Dispose();   
    MessageBox.Show("Complete");   
}   
  
void Bw_DoWork(object sender, DoWorkEventArgs e)   
{   
    if (thisFunction != null)   
        thisFunction();   
}

Add a start function, which will run the BackgroundWorker and show up the loading form.

public void Start()   
{   
    Bw.RunWorkerAsync();   
    newLoading = new LoadingForm();   
    newLoading.ShowDialog();   
}

That's it for the simple loading class.

Using this Class

Add a method, this will run asynchronously.

public void Counter()   
{   
    for (int i = 0; i <= Maximum; i++)   
    {   
        Idx = i;   
    }   
}

Create a new class and associate the new method with this class. Then run the class by using its Start method.

private void button5_Click(object sender, EventArgs e)   
{   
    LoadingClass.BackgroundLoading BL = new LoadingClass.BackgroundLoading(Counter);   
    BL.Start();   
}

That's it! You could try the code examples to see how it really works.

Points of Interest

BackgroundWorker is a great control which help us to run multi-threads much easier. Using it effectively could make your app much more professional and user friendly.

As I only try to cover a basic approach to BackgroundWorker, the class was just a simple example. There is a lot of room for improvement. You could add a timer to see how long it runs, or add a GIF animation to make it look cool?

History

  • 5th March, 2009: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

hieuuk
Software Developer Freelance
Vietnam Vietnam
After the success with my personal website hieu.co.uk(about Software dev and web dev), I decide to port some of my tutorial to CodeProject as I think it would be useful.
 
My main purpose is to share my experience, learn more from community and make more friend ^o^.

Comments and Discussions

 
GeneralMy vote of 5 PinmemberRupaliPawar3-Oct-10 20:29 
GeneralGood basic article PinmemberDonsw24-Mar-09 10:51 
QuestionNice article PinmemberKhayralla10-Mar-09 17:32 
GeneralAnother option with a bit less copy and paste each time you use it PinmemberPaul B.10-Mar-09 10:10 
QuestionBackground worker or new thread? Pinmembersupercat96-Mar-09 5:27 
GeneralMy vote of 2 Pinmembermarco_br6-Mar-09 5:18 
GeneralRe: My vote of 2 Pinmemberhieuuk6-Mar-09 5:57 
GeneralAn example project would be nice Pinmembersmesser6-Mar-09 4:41 
I am trying to follow your example would you please email me a sample project?
AnswerRe: An example project would be nice Pinmemberhieuuk6-Mar-09 5:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 5 Mar 2009
Article Copyright 2009 by hieuuk
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid