为什么这个线程方法需要900毫秒才能完成?

时间:2010-11-01 13:03:37

标签: c# .net multithreading optimization

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
    }
}

4 个答案:

答案 0 :(得分:8)

您无法更新UI线程之外的UI组件。所有这些Invoke调用都将更新编组回UI线程,再次有效地序列化您的应用程序。

大树的典型方法是仅在扩展父级时加载子节点,而不是在开始时尝试填充整个树。

答案 1 :(得分:3)

InvokeRequired需要一些时间来完成它的工作。见this。特别 “如果控件的句柄尚不存在,则InvokeRequired 搜索控件的父链,直到找到具有窗口句柄的控件或表单。如果找不到合适的句柄,则InvokeRequired方法返回假。” 所以需要一些时间

答案 2 :(得分:3)

首先,为什么你使用线程容易?看起来有点过度设计。但你可能没有向我们展示一切吗?

还用以下内容包装TreeView修改:

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

获得更好的表现。

答案 3 :(得分:2)

在清除和添加新节点之前,您是否在BeginUpdate控件上调用TreeView,然后在添加节点时调用EndUpdate?如果你不进行这些调用,你的TreeView将在每个添加的节点之后尝试重新绘制自己 - 缺少这个可以使代码运行得非常慢,特别是在添加大量节点时。