C# 加快将字符串列表加载到树视图的速度
Stackflow和C#新手在这里 下面我有一些代码,它将字符串列表加载到treeview控件中,效果很好。唯一的问题是速度。当列表很大时,加载需要时间,这不是问题,只是它会锁定UI一段时间 因此,一个示例是这样的字符串列表(但要大得多): c:\drivers\test1.txtC# 加快将字符串列表加载到树视图的速度,c#,multithreading,winforms,treeview,C#,Multithreading,Winforms,Treeview,Stackflow和C#新手在这里 下面我有一些代码,它将字符串列表加载到treeview控件中,效果很好。唯一的问题是速度。当列表很大时,加载需要时间,这不是问题,只是它会锁定UI一段时间 因此,一个示例是这样的字符串列表(但要大得多): c:\drivers\test1.txt c:\drivers\test2.txt c:\drivers\folder\test1.txt c:\brother\tester\text1.zip c:\brother\other\text2.zip c:\d
c:\drivers\test2.txt
c:\drivers\folder\test1.txt
c:\brother\tester\text1.zip
c:\brother\other\text2.zip
c:\data\company1\accounts.rar
c:\data\company2\accounts.rar
treeview使用反斜杠标记拆分字符串,并将它们整齐地放在浏览器视图中-这很好 tvRestore是示例中的Treeview控件
foreach (string path in lstKeys)
{
lastNode = null;
subPathAgg = string.Empty;
foreach (string subPath in path.Split(new string[] { "\\" }, StringSplitOptions.None))
{
foreach (string item in subPath.Split(new string[] { "\\" }, StringSplitOptions.None))
{
if (item == "" || item == null)
{
continue;
}
subPathAgg += item + "\\";
TreeNode[] n = tvRestore.Nodes.Find(subPathAgg, true);
if (n.Length > 0)
{
lastNode = n[0];
continue;
}
else
{
// lastNode = null;
}
TreeNode[] nodes = tvRestore.Nodes.Find(subPathAgg, true);
if (nodes.Length == 0)
if (lastNode == null)
lastNode = tvRestore.Nodes.Add(subPathAgg, item);
else
lastNode = lastNode.Nodes.Add(subPathAgg, item);
else
lastNode = nodes[0];
}
}
}
唯一的问题是速度。我尝试使用线程,但代码异常,因为控件位于不同的线程上。我认为我必须调用节点。添加,但我不知道如何执行此操作
理想情况下,当应用程序启动时,代码将开始填充treeview,尽管我不希望应用程序锁定30-40秒或更长的时间以获得更大的列表
加快这一进程的最佳方式是什么 您可以做几件事,包括在后台运行它-我喜欢使用Task.Run()来实现这一点
private void Form1_Load(object sender, EventArgs e)
{
// Show the user something
treeView1.Nodes.Add("Loading...");
// Run the tree load in the background
Task.Run(() => LoadTree());
}
然后,您的任务可以构建一个包含所有新节点的树节点,并调用树视图将新节点添加为一个范围,以及使用BeginUpdate…EndUpdate阻止可视化更新,直到加载所有节点
private void LoadTree()
{
// Get a list of everything under the users' temp folder as an example
string[] fileList;
DirectoryInfo df = new DirectoryInfo(Path.GetTempPath());
fileList = df.GetFiles("*.*",SearchOption.AllDirectories).Select<FileInfo, string>((f) => f.FullName).ToArray();
// Parse the file list into a TreeNode collection
TreeNode node = GetNodes(new TreeNode(), fileList);
// Copy the new nodes to an array
int nodeCount = node.Nodes.Count;
TreeNode[] nodes = new TreeNode[nodeCount];
node.Nodes.CopyTo(nodes, 0);
// Invoke the treeview to add the nodes
treeView1.Invoke((Action)delegate ()
{
treeView1.BeginUpdate(); // No visual updates until we say
treeView1.Nodes.Clear(); // Remove existing nodes
treeView1.Nodes.AddRange(nodes); // Add the new nodes
treeView1.EndUpdate(); // Allow the treeview to update visually
});
}
在我的机器上,以这种方式将56000个节点加载到treeview大约需要1.5秒,并且UI没有阻塞。在使用
treeview.BeginUpdate()添加节点之前,请尝试关闭图形
然后使用EndUpdate()将其重新打开代码>
private TreeNode GetNodes(TreeNode parent, string[] fileList)
{
// build a TreeNode collection from the file list
foreach (string strPath in fileList)
{
// Every time we parse a new file path, we start at the top level again
TreeNode thisParent = parent;
// split the file path into pieces at every backslash
foreach (string pathPart in strPath.Split('\\'))
{
// check if we already have a node for this
TreeNode[] tn = thisParent.Nodes.Find(pathPart, false);
if (tn.Length == 0)
{
// no node found, so add one
thisParent = thisParent.Nodes.Add(pathPart,pathPart);
}
else
{
// we already have this node, so use it as the parent of the next part of the path
thisParent = tn[0];
}
}
}
return parent;
}