Click here to Skip to main content
15,881,380 members
Articles / Programming Languages / C#
Article

Populating TreeView on a Background Thread

Rate me:
Please Sign up or sign in to vote.
4.25/5 (11 votes)
12 Jul 2008CPOL2 min read 88.3K   3.9K   42   12
An article on how to populate large TreeViews on a background thread
Image 1

Introduction

Sometimes we have to present really large TreeViews on our forms. Creating and filling up such a large TreeView takes lot of time and the form is blocked meanwhile - we cannot use the other controls.

You would think that filling up the TreeView on a separate thread solves the problem. The problem is that multithreading itself is not enough; we have to use some tricks. Here you can see a very simple solution for the problem.

Background: Multithreading

In only a few words, multithreading makes it possible to run several tasks parallel. We would like to use our controls on the form -edit a textbox for example- while the TreeView is loading.

With this solution, we use BackgroundWorker that is a library class for multithreading.

The Problem: Simple Multithreading Does Not Work

The easiest way would be simple multithreading:

C#
public void FillTree()
{
    for (int i = 0; i < 10; i++)
    {
        tn = treeView1.Nodes.Add(i.ToString());
        for (int j = 0; j < 10; j++)
        {
            tn.Nodes.Add(((int)(i * 10 + j)).ToString());
            System.Threading.Thread.Sleep(100);
        }
    }
}

private void Form2_Load(object sender, EventArgs e)
{
    System.Threading.Thread th = new System.Threading.Thread(FillTree);
    th.Start();
}

The only problem with this solution is that it does not work. We get an InvalidOperationException saying: "Action being performed on this control is being called from the wrong thread. Marshal to the correct thread using Control.Invoke or Control.BeginInvoke to perform this action." When you add a node to the TreeView, you have to be on the right thread. To do so, we will use Control.Invoke.

The Trick: Multithreading & Invoke

In the previous section, we realised that we need more than simple multithreading. We get an exception if we try to add a node to the TreeView from a separate thread. What can we do? Add the node from the TreeView's thread.

To execute an operation in the TreeView's thread context, we have to call its Invoke method:

C#
treeView1.Invoke(new Add(Add1), new object[] { i });

Invoke consumes delegates. Here in this sample, we defined only one delegate for the two Add* functions:

C#
public delegate void Add(int i);

Now our solution works as follows: when the form is opening, we start to run the TreView filling logic on a separate thread. Every time it reaches the point when a new node has to be added to the TreeView, it calls TreeView's Invoke which adds the node from the TreeView's thread.

Start the new thread with BackgroundWorker.RunWorkerAsync when the form is loading:

C#
private void Form1_Load(object sender, EventArgs e)
{
    backgroundWorker1.RunWorkerAsync();
}

Call the filling subroutine in the background thread (we have to handle BackgroundWorker.DoWork):

C#
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    FillTree();
}

The filling subroutine calls back to the TreeView's thread when it adds a node:

C#
public void FillTree()
{
    for (int i = 0; i < 10; i++)
    {
        treeView1.Invoke(new Add(Add1), new object[] { i });
        for (int j = 0; j < 10; j++)
        {
            treeView1.Invoke(new Add(Add2), new object[] { i * 10 + j });
        }
    }
}

For more details, please see the attached source code.

History

  • 11th July, 2008: Initial version

License

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


Written By
Engineer
Hungary Hungary
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionThank you <3 Pin
Orphraie10-Dec-19 13:10
Orphraie10-Dec-19 13:10 
PraiseThanks!! Pin
e.Cebel22-Aug-19 0:08
e.Cebel22-Aug-19 0:08 
GeneralMy 2 cents. Pin
Iker876-Oct-16 19:18
Iker876-Oct-16 19:18 
SuggestionMy 2 cents. Pin
Iker876-Oct-16 19:18
Iker876-Oct-16 19:18 
GeneralRe: My 2 cents. Pin
Frits van Soldt 202227-Oct-22 1:38
Frits van Soldt 202227-Oct-22 1:38 
QuestionVery good tuto Pin
procra23-Oct-13 8:58
procra23-Oct-13 8:58 
Generalin most cases the filling speed is not the problem... Pin
Mr.PoorEnglish12-Jul-08 13:03
Mr.PoorEnglish12-Jul-08 13:03 
GeneralRe: in most cases the filling speed is not the problem... Pin
izotov12-Jul-08 20:56
izotov12-Jul-08 20:56 
GeneralRe: in most cases the filling speed is not the problem... Pin
Member 239204115-Jun-17 5:27
Member 239204115-Jun-17 5:27 
Generalhad to modify FillTree() Pin
Sergei Vedischev12-Jul-08 8:47
Sergei Vedischev12-Jul-08 8:47 

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

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