2011-05-19 102 views
2

我已经在C#中编写了递归目录遍历方法(从asp.net页面托管)。代码按照我的意图工作(我枚举目标机器上的共享列表,然后递归共享并将每个文件/目录添加到TreeView中)。不幸的是,这消耗了大量的内存,并且需要很长时间才能运行,打开aspx页面会导致Webdev.Webserver内存使用率猛增到800兆,查看页面的Chrome实例消耗大量1.5GB内存! (针对本地工作站上托管的SMB共享运行测试代码)我甚至无法查看页面源,而无需挂镀铬。递归目录遍历/树占用大量内存

foreach (TreeNode n in FileSelectList.Nodes) 
{ 
    Dir_Node_Recurse(n, hostName); 
    //break; 
} 

取消注释// break;语句只会导致正在处理的第一个目录共享,而这会消耗更少的内存。 FileSelectList是一个Asp:TreeView。

public static void Dir_Node_Recurse(TreeNode node, string hostName) 
{ 
     DirectoryInfo dir = new DirectoryInfo(String.Format(@"\\{0}\{1}", 
                  hostName, 
                  node.ValuePath.ToString() 
                  )); 
     TreeNode tNode; 
     foreach (var i in dir.EnumerateDirectories()) 
     { 
      tNode = new TreeNode(i.Name.ToString()); 
      node.ChildNodes.Add(tNode); 
      Dir_Node_Recurse(tNode, hostName); 
     } 

     foreach (var i in dir.EnumerateFiles()) 
     { 
      node.ChildNodes.Add(new TreeNode(i.Name.ToString())); 
     } 
} 

由于创建了大量的TreeNode对象,这似乎会导致极度的资源使用。我是否应该创建自己的节点类型以最大限度地减少内存使用量,或者是否有其他技术可以使其可用?

+2

为什么你必须首先枚举所有的文件夹,而不是等待用户输入 - 如果用户可以选择是否钻入特定的文件夹,这不是一个好时机来看看@的内容文件夹? – 2011-05-19 22:10:10

回答

0

是否有你需要获取所有节点的原因?你可以使用随需应变方法吗?

您还可以剖析代码。您可以尝试将代码指向较小的目录并观察其行为。

+0

那么我打算制作方法来处理所有选定的文件,这个树上有一个复选框。此外,我希望能够存储哪些文件被选中的列表(在SQL中),以及何时加载页面,根据存储的数据填充复选框。我会尝试一下您的点击式方法,看看我是否可以提高加载效率。 – CJD 2011-05-19 22:38:01

0

你想做什么?

您正在创建一个巨大的页面,并询问如何使它消耗更少的内存?这是显而易见的 - 不要在页面中显示所有的树,无论如何,它永远不会对任何用户有用。

例如,您可以将输出限制为只有几个级别。

+0

那么这个应用程序的上下文是一个SMB备份实用程序a-la veritas,只能通过HTTP运行,并将windows服务作为后端。我希望列举的文件和目录可以选择作为备份目标。我可以在用户遍历目录时动态执行此操作,但是仍然让我感到紧张,即如果用户扩展了足够多的目录树,它仍然会使webbrowser螺旋失去控制。 – CJD 2011-05-19 23:15:40