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
}
}
答案 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
将在每个添加的节点之后尝试重新绘制自己 - 缺少这个可以使代码运行得非常慢,特别是在添加大量节点时。