-2

这里是完整的源代码: 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();
}

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

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

4

1 回答 1

3

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

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

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

DoWork如果您的后台工作人员应该这样做。然后您可以Result根据它生成的结果设置BGW的属性,以便以后使用。

对于 UI 部分,即treeView1.Nodes.Add(调用,应该在RunWorkerCompleted事件中。该事件旨在让您根据长时间运行的任务的结果来操作 UI。在那里您可以读取ResultBGW 的属性(它是传递给事件处理程序的参数中的属性),并且可以将数据添加到树视图中。由于这是在 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);
}
于 2013-09-11T19:50:50.910 回答