2016-07-06 170 views
0

我有運行和分配一個新的樹視圖對象到treeFolders樹視圖形式對象這段代碼:異步使用異步和等待更新Winforms中一個TreeView

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

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

    } 

我很高興作爲代碼不阻擋用戶界面,並遞歸目錄並建立一個TreeView對象。問題是,即使在運行此代碼之後,窗體上的TreeFolders TreeView對象仍然爲空。如果我在break模式下檢查treeFolders對象,我可以看到它確實有文件和目錄的節點,所以我不明白爲什麼它不顯示它們。這是否與樹視圖創建對UI線程的不同威脅有關?下面是這似乎是做工精細的ListDirectory和負載所需的所有目錄和文件

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

您不應在線程池線程上創建UI對象。相反,在內存中創建一個樹結構並從ListDirectory方法返回它,然後讓你的UI線程創建實際的UI對象('TreeNode'等)。 –

+0

因爲你這樣做是C目錄你確定你沒有得到未經授權的例外嗎?輸出窗口在運行應用程序時說什麼 – WBuck

+0

try catch塊處理未授權的異常 – ravetroll

回答

1

你通過調用使用Task.Run頂層的方法調用執行在非UI線程操作的全部 。但是你需要與UI交互的代碼在UI線程中運行,而不是非UI線程。

你應該在非UI線程在非UI線程表演長時間運行的非UI操作,而不是所有操作。所以這意味着只需在Task.Run的調用中調用GetFilesGetDirectories,剩下的代碼(這是您的UI代碼)在UI線程中運行。