Create a Worker Thread for your Windows Form in C#


When performing a relatively heavy operation on your Windows Form, what often happens is that your application’s UI will freeze until the heavy operation completes. This is usually unacceptable because your application’s end user will think it crashed and probably try to close it. To solve this problem you need to run your heavy operation on a separate thread from that of your UI. This way you will be able to run your operation while also keep the end user informed of the progress from the UI. In this article I will show you how to do just that.

First let’s create a form with a textbox which displays the progress of the heavy operation, and two buttons, one to start the process and one to stop it.

Next we need to create our heavy operation method. For this example let’s just create a loop which iterates for 1 million times.

private void HeavyOperation()
{
    // Example heavy operation
    for (int i = 0; i <= 999999; i++)
    {
    }
}

Now let’s declare our thread and a boolean flag used to stop the heavy operation. We must use the System.Threading namespace to access the Thread class.

// Declare our worker thread
private Thread workerThread = null;

// Boolean flag used to stop the
private bool stopProcess = false;

Next in the start button event handler method, we will initialise the thread and tell it to run the HeavyOperation method.

private void btnStart_Click(object sender, EventArgs e)
{
    this.stopProcess = false;

    // Initialise and start worker thread
    this.workerThread = new Thread(new ThreadStart(this.HeavyOperation));
    this.workerThread.Start();
}

Your code should be able to compile and run but you won’t see anything happening because we still have to display the heavy operation’s progress on the UI.

This is where Delegates come in. In .NET a delegate is a form of type-safe function pointer. From the HeavyOperation method which is being run under the worker thread, we cannot access the UI thread directly because it would cause a cross-thread operation exception. This is because the UI thread and our worker thread are running independently of each other and cannot access objects which have not been created by themselves.

So to write to our status textbox which is on the UI from our worker thread, we must use a delegate. At the top of our class declare a delegate and an instance of the delegate as shown below:

// Declare a delegate used to communicate with the UI thread
private delegate void UpdateStatusDelegate();
private UpdateStatusDelegate updateStatusDelegate = null;

Next initialise the delegate in form load for example:

private void Form1_Load(object sender, EventArgs e)
{
    // Initialise the delegate
    this.updateStatusDelegate = new UpdateStatusDelegate(this.UpdateStatus);
}

As you can see in the above code, the delegate is being passed the method name UpdateStatus. This method will be used to display activity indication to the end user. Now let’s create the method:

private void UpdateStatus()
{
    this.txtProgress.Text += "*";
}

Next, let’s update our HeavyOperation method to call the delegate, which updates the status:

private void HeavyOperation()
{
    // Example heavy operation
    for (int i = 0; i <= 999999; i++)
    {
        // Check if Stop button was clicked
        if (!this.stopProcess)
        {
            // Show progress
            this.Invoke(this.updateStatusDelegate);
        }
        else
        {
            // Stop heavy operation
            this.workerThread.Abort();
        }
    }
}

As you can see, to call the delegate we are using the Invoke keyword, which executes the delegate on the UI thread, since we are calling Invoke from the this object.

And to add the final touch to our application, we must add an event handler for the stop button and set the stopProcess flag to true.

private void btnStop_Click(object sender, EventArgs e)
{
    this.stopProcess = true;
}

Now if you run the application and click on your start button, you will see the status textbox filling up with the “*” character. What’s happening is your worker thread is iterating for 1 million times and for each iteration a star is written to the textbox using the delegate.

Advertisements
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: