树视图未在后台更新

本文关键字:后台 更新 视图 | 更新日期: 2023-09-27 18:30:55

这里是完整的源代码: http://pastebin.com/mLaGwwi0正如您会注意到的,事情是扫描目录和文件并在树视图中填充它们。我正在使用后台工作线程(与 Threads 类发生的情况相同)在后台执行此操作,同时使用节点逐个更新树视图。问题是它无法在后台工作,也没有更新树视图。这是悬挂表单的代码部分:

public void ListDirectory(DirectoryInfo path)
{
    treeView1.Nodes.Add(CreateDirectoryNode(path));
}
public void Addnode(DirectoryInfo dirinfo)
{
    Invoke(new AddCDAnode(ListDirectory), new object[] { dirinfo });
}
private TreeNode CreateDirectoryNode(DirectoryInfo directoryInfo)
{
    var directoryNode = new TreeNode(directoryInfo.Name);
    foreach (var directory in directoryInfo.GetDirectories())
    {
        //Statustext = directory.FullName;
        directoryNode.Nodes.Add(CreateDirectoryNode(directory));
    }
    foreach (var file in directoryInfo.GetFiles())
    directoryNode.Nodes.Add(new TreeNode(file.Name));
    return directoryNode;
}
public delegate void AddCDAnode(DirectoryInfo dirinfo);
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    DirectoryInfo dir = new DirectoryInfo(@"''server'trabajos 2013'");
    Addnode(dir);
}
private void Form1_Load(object sender, EventArgs e)
{
    //Start filling the TreeView on a separate thread
    backgroundWorker1.RunWorkerAsync();
}

在完整的源代码中,您将看到注释的代码 - 这是来自示例并在后台工作没有任何麻烦。所以我认为问题出在我的扫描目录代码上。

如果您想下载该解决方案,也可以在此处获得。

树视图未在后台更新

问题是你启动了一个后台线程,但随后立即调用Invoke在 UI 线程中运行基本上所有的真实代码,因此 UI 线程被阻止。

您需要做的是将 UI 逻辑与非 UI 逻辑分开。 确保在后台线程中执行非 UI 逻辑,并在 UI 线程中执行 UI 逻辑。

在这种情况下,CreateDirectoryNode(path)基本上是所有非 UI 工作。 它正在执行一大堆文件操作(这很耗时),并且通常会创建您的 UI 稍后将使用的数据。

这应该在后台辅助角色DoWork事件中完成。 然后,您可以根据 BGW 生成的结果设置 BGW 的 Result 属性,以便以后可以使用。

对于 UI 部分(即treeView1.Nodes.Add(调用),应位于 RunWorkerCompleted 事件中。 该事件旨在让您根据长时间运行的任务的结果操作 UI。 在那里,您可以读取 BGW 的 Result 属性(它是传递给事件处理程序的参数中的一个属性),在那里它可以将数据添加到树视图中。 由于这是在 UI 线程中,因此不会获得跨线程异常,并且由于长时间运行的文件 IO 是在后台线程中完成的,因此它不会处理 UI。

因此,您所需要的只是您的CreateDirectryNode方法和以下内容:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    DirectoryInfo dir = new DirectoryInfo(@"''server'trabajos 2013'");
    e.Result = CreateDirectoryNode(dir);
}
//TODO ensure that this event handler is added to your BGW so it actually fires
void Form1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    treeView1.Nodes.Add((TreeNode)e.Result);
}