1

我已经编写了一些相当快速的代码,自从将其更改为“SearchOption.AllDirectories”后,甚至只需加载表单/应用程序就需要一整分钟。

我能做些什么来让这个应用程序在加载时运行得更快吗?任何帮助/信息将不胜感激。

谢谢。

private const string path = @"R:\Folder One\Folder Two\Folder Three";

public frmMain()
{
    InitializeComponent();

    ListDirectory(treeView1, path);
    treeView1.SelectedNode = treeView1.Nodes[0];
    treeView1.SelectedNode.Expand();
}

private void ListDirectory(TreeView treeView, string path)
{
    treeView.Nodes.Clear();
    var rootDirectoryInfo = new DirectoryInfo(path);
    treeView.Nodes.Add(CreateDirectoryNode(rootDirectoryInfo));
}

private TreeNode CreateDirectoryNode(DirectoryInfo directoryInfo)
{
    var directoryNode = new TreeNode(directoryInfo.Name);
    foreach (var directory in directoryInfo.GetDirectories())
    {
        if (!directory.Name.Contains("_") 
             && !directory.Name.Contains("Word Versions") 
             && !directory.Name.Contains("Visio Flowcharts"))
        {
            var dirFileCount = directory.EnumerateFiles(
                         "*.pdf", SearchOption.AllDirectories).Count();
            dirFileCount += directory.EnumerateFiles(
                         "*.xls", SearchOption.AllDirectories).Count();
            dirFileCount += directory.EnumerateFiles(
                         "*.doc", SearchOption.AllDirectories).Count();
            dirFileCount += directory.EnumerateFiles(
                         "*.xlsx", SearchOption.AllDirectories).Count();
            dirFileCount += directory.EnumerateFiles(
                         "*.docx", SearchOption.AllDirectories).Count();
            dirFileCount += directory.EnumerateFiles(
                         "~*", SearchOption.AllDirectories).Count();

            if (dirFileCount != 0)
                directoryNode.Nodes.Add(CreateDirectoryNode(directory));
        }
    }

    foreach (var file in directoryInfo.GetFiles())
    {
        if (file.Extension.Equals(".pdf") 
           || file.Extension.Equals(".xls") 
           || file.Extension.Equals(".doc") 
           || file.Extension.Equals(".xlsx") 
           || file.Extension.Equals(".docx"))
        {
            if (!file.Name.Contains("~") 
                        || !file.Name.Contains("$"))
                directoryNode.Nodes.Add(new TreeNode(file.Name));
        }
    }
    return directoryNode;
}
4

4 回答 4

5

这:

var dirFileCount = directory.EnumerateFiles("*.pdf", SearchOption.AllDirectories).Count();
dirFileCount += directory.EnumerateFiles("*.xls", SearchOption.AllDirectories).Count();
dirFileCount += directory.EnumerateFiles("*.doc", SearchOption.AllDirectories).Count();
dirFileCount += directory.EnumerateFiles("*.xlsx", SearchOption.AllDirectories).Count();
dirFileCount += directory.EnumerateFiles("*.docx", SearchOption.AllDirectories).Count();
dirFileCount += directory.EnumerateFiles("~*", SearchOption.AllDirectories).Count();

if (dirFileCount != 0)
    directoryNode.Nodes.Add(CreateDirectoryNode(directory));

是完全错误的。

每个都EnumerateFiles将重新扫描特定类型文件的所有子目录。更糟糕的是:您正在计算总共有多少个文件类型,但您想要的是“是否有任何文件的扩展名”?因此,在找到第一个文件后,.pdf您可以停止。

您应该搜索“*”,然后按您想要的扩展名进行过滤,在找到的第一个文件处停止。

var dirFileCount = from p in directory.EnumerateFiles("*", SearchOption.AllDirectories)
                   let extension = p.Extension
                   where extension.Equals("pdf", StringComparison.OrdinalIgnoreCase) ||
                         extension.Equals("xls", StringComparison.OrdinalIgnoreCase) ||
                         extension.Equals("doc", StringComparison.OrdinalIgnoreCase) ||
                         extension.Equals("xlsx", StringComparison.OrdinalIgnoreCase) ||
                         p.Name.StartsWith("~")
                   select p;

if (dirFileCount.Any())
{
    directoryNode.Nodes.Add(CreateDirectoryNode(directory));
}

可能更好。

你确定你必须在子文件夹中搜索吗?因为SearchOption.AllDirectories将在子文件夹中搜索,而不仅仅是在给定文件夹中。

于 2013-09-06T08:27:47.393 回答
0

为什么不只是在表单加载时加载根目录,然后在用户展开该节点时加载每个子节点。

除此之外,您为什么不考虑使用BackgroundWorker 类来使用户界面更具交互性?

BackgroundWorker 类允许您在单独的专用线程上运行操作。下载和数据库事务等耗时的操作可能会导致您的用户界面 (UI) 在运行时似乎停止响应。当您需要响应式 UI 并且面临与此类操作相关的长时间延迟时,BackgroundWorker 类提供了一种方便的解决方案。

于 2013-09-06T08:14:14.870 回答
0

在单独的线程中运行您的代码

Thread yourThread = new System.Threading.Thread(delegate(){
          //Your code 
 });
yourThread.Start();

更新主线程控件时要小心,您需要使用 Invoke ,例如在 WPF 应用程序中

Dispatcher.Invoke(new Action(delegate()
                 // your code that update main thread controls
                {}));
于 2013-09-06T08:20:08.783 回答
-1

int doc_filescount = directory_info.GetFileSystemInfos("*.doc").Length;

IT 将在一个目录中生成(“.doc”和“.docx”)文件计数

于 2013-11-28T06:06:43.313 回答