简体   繁体   中英

Async Updating a TreeView in Winforms using async and await

I have this piece of code running and assigning a new TreeView object to the treeFolders TreeView form object:

private async void butLoad_Click(object sender, EventArgs e)
    {

        Task<TreeView> task = Task.Run(() => DirectoryTree.ListDirectory("C:\\"));
        this.treeFolders = await task;

    }

I am happy as the code does not block the UI while it goes and recurses the directories and builds a TreeView object. The problem is that the treeFolders TreeView object on my form remains empty even after running this code. If I examine the treeFolders object in break mode I can see it does indeed have Nodes for the files and directories so I cannot understand why it is not displaying them. Is it to do with the fact the TreeView was created on a different threat to the UI thread? Here is the ListDirectory which seems to work fine and loads all the required directories and files

public class DirectoryTree
{
    public static async Task<TreeView> ListDirectory(string path)
    {
        TreeView treeView = new TreeView();
        var rootDirectoryInfo = new DirectoryInfo(path);
        treeView.Nodes.Add(await CreateDirectoryNode(rootDirectoryInfo));
        return treeView;

    }

    private static async Task<TreeNode> CreateDirectoryNode(DirectoryInfo directoryInfo)
    {
        try
        {
            var directoryNode = new TreeNode(directoryInfo.Name);
            foreach (var directory in directoryInfo.GetDirectories())
                directoryNode.Nodes.Add(await CreateDirectoryNode(directory));
            foreach (var file in directoryInfo.GetFiles())
                directoryNode.Nodes.Add(new TreeNode(file.Name));
            return directoryNode;
        }
        catch ( Exception ex)
        {
            var directoryNode = new TreeNode(directoryInfo.Name);
            return directoryNode;
        }
    }
}

You're performing the entirety of the operation in a non-UI thread by calling the top level method call using Task.Run . But you need the code interacting with the UI to run in the UI thread, not a non-UI thread.

You should be performing only the long running non-UI operations in a non-UI thread, rather than all operations in a non-UI thread. So this means simply calling GetFiles and GetDirectories inside of a call to Task.Run , leaving the rest of the code (which is your UI code) to run in the UI thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM