1
private void Form1_Load(object sender, System.EventArgs e)
{
    StartToFillTree();
}

private void StartToFillTree( )
{
    try
    {
        tvFolders.Nodes.Clear();
        tvFolders.Nodes.Add( new TreeNode("Loading", -1, -1) );

        Thread explorerThread = new Thread( new ThreadStart( FillTreeInAnotherThread ) );
        explorerThread.Start();
    }
    catch (Exception exc)
    {
        //Do the catch
    }
}

private void FillTreeInAnotherThread()
{
    try
    {
        CreateTree(this.tvFolders);
    }
    catch (Exception exc)
    {
        //Do the catch
    }
}


public void ClearTreeview( TreeView tv ) 
{
    tv.Nodes.Clear();
}

public void AddNodeToTreeview( TreeView tv, TreeNode node ) 
{
    tv.Nodes.Add( node );
}

public void CreateTree(TreeView treeView)
{
    try
    {
        TreeNode hoofdNode = new TreeNode( "NodeNam", 0, 0);
        AddDrivesToHoofdNode(hoofdNode); //This method takes 1 ms

        //This part takes 905 milliseconds if I can believe my profiler !!?? -----
        if( treeView.InvokeRequired )
        {
            treeView.Invoke( new ClearTreeviewDelegate( this.ClearTreeview ), new object[] { treeView } );
            treeView.Invoke( new AddNodeToTreeviewDelegate( this.AddNodeToTreeview ), new object[] { treeView, hoofdNode } );
        }
        else
        {
            treeView.Nodes.Clear();
            treeView.Nodes.Add(hoofdNode);
        }
        //End of 900ms part ?? -----


        AddFavorieteFolders(treeView);//This method takes 1 ms

    }
    catch (Exception ex)
    {
        //Do some catching
    }
}
Run CMD
  • 2,937
  • 3
  • 36
  • 61
  • 3
    Why do you have empty catch blocks? This is bad practice. Better not catch an exception than silently swallow it. – Oded Nov 01 '10 at 13:08
  • 1
    I'm catching the errors, but just removed the code for easy reading purposes here :-) – Run CMD Nov 01 '10 at 13:19

4 Answers4

8

You can't update UI components outside the UI thread. All those Invoke calls are marshalling the updates back to the UI thread, effectively serialising your app again.

A typical approach to large trees is only loading child nodes when the parent is expanded rather than trying to fill the whole tree at the beginning.

Paolo
  • 22,188
  • 6
  • 42
  • 49
3

InvokeRequired takes some time to do its work. See this. Especially "If the control's handle does not yet exist, InvokeRequired searches up the control's parent chain until it finds a control or form that does have a window handle. If no appropriate handle can be found, the InvokeRequired method returns false." So it takes some time

fedotoves
  • 757
  • 6
  • 7
3

First of all, why are you using threads for something that easy? Looks a bit over-designed. But you are maybe not showing us everything?

Also wrap the TreeView modifications with:

treeView.BeginUpdate();
// modify the tree here.
treeView.EndUpdate();

To get better performance.

jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • You're right ... I was starting another thread to add 1 node to a treeview .. :-) a bit overkill :-) (it had grown over the years) ... It now takes 1 ms to complete. Thanks. – Run CMD Nov 01 '10 at 13:38
  • np. happens the best of us ;) – jgauffin Nov 01 '10 at 13:41
2

Are you calling BeginUpdate on your TreeView control before clearing and adding new nodes, and then calling EndUpdate when you're done adding nodes? If you don't make these calls, your TreeView will attempt to repaint itself after each added node - missing this can make code that is otherwise fine run extremely slowly, especially when adding a large number of nodes.

MusiGenesis
  • 74,184
  • 40
  • 190
  • 334