2016-07-06 6 views
0

Ich habe dieses Stück Code ausgeführt wird und ein neues TreeView Objekt in die treeFolders TreeView Form Objekt zuweisen:Async Aktualisieren eines TreeView in WinForms Asynchron mit und warten

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

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

    } 

Ich bin glücklich, da der Code nicht blockiert UI, während es geht und recurses die Verzeichnisse und baut ein TreeView-Objekt. Das Problem besteht darin, dass das treeFolders-TreeView-Objekt in meinem Formular auch nach dem Ausführen dieses Codes leer bleibt. Wenn ich das treeFolders-Objekt im Unterbrechungsmodus untersuche, kann ich sehen, dass es tatsächlich Knoten für die Dateien und Verzeichnisse gibt, so dass ich nicht verstehen kann, warum sie nicht angezeigt werden. Hat es damit zu tun, dass TreeView auf einer anderen Bedrohung des UI-Threads erstellt wurde? Hier ist die Listdirectory, die Task.Run durch den Aufruf der Top-Level-Methodenaufruf mit feinen und lädt alle erforderlichen Verzeichnisse und Dateien

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; 
     } 
    } 
} 
+0

Sie sollten keine UI-Objekte in Threadpool-Threads erstellen. Erstellen Sie stattdessen eine Baumstruktur im Speicher und geben Sie sie aus Ihrer 'ListDirectory'-Methode zurück, und anschließend erstellt Ihr Benutzeroberflächenthread die tatsächlichen UI-Objekte (' TreeNode' usw.). –

+0

Weil Sie dies tun, ist das C-Verzeichnis, sind Sie sicher, dass Sie nicht nicht autorisierte Ausnahmen bekommen? Was sagt Ihr Ausgabefenster beim Ausführen der App? – WBuck

+0

Der try catch-Block behandelt die nicht autorisierten Ausnahmen – ravetroll

Antwort

1

Sie Durchführung der Gesamtheit des Betriebs in einem nicht-UI-Thread zu funktionieren scheint . Sie benötigen jedoch den Code, der mit der Benutzeroberfläche interagiert, um im Benutzeroberflächenthread ausgeführt zu werden, nicht mit einem Nicht-UI-Thread.

Sie sollten nur die langen Lauf nicht-UI-Operationen in einem nicht-UI-Thread durchführen, anstatt alle Operationen in einem Thread nicht-UI. Das bedeutet, dass Sie einfach GetFiles und GetDirectories innerhalb eines Anrufs an Task.Run anrufen und den Rest des Codes (den UI-Code) im UI-Thread ausführen.