为什么这个 C# 代码这么慢?需要优化目录/文件搜索和添加
本文关键字:文件 搜索 添加 优化 代码 为什么 | 更新日期: 2023-09-27 18:30:18
我写了一些相当快的代码,自从将其更改为"SearchOption.AllDirectory"以来,即使只是加载表单/应用程序也需要整整一分钟。
我可以做些什么来使此应用程序在加载时运行得更快?任何帮助/信息将不胜感激。
谢谢。
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;
}
这个:
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));
完全是 w r o n g。
每个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
将在子文件夹中搜索,而不仅仅是在给定的文件夹中。
为什么不在表单加载时加载根目录,然后在用户扩展该节点后加载每个子节点。
此外,您为什么不考虑使用BackgroundWorker Class来使用户界面更具交互性呢?
类允许您在 单独的专用线程。耗时的操作,如下载 和数据库事务可能会导致您的用户界面 (UI) 看起来 好像它在运行时停止响应。当你 想要一个响应式 UI,而您面临着相关的长时间延迟 通过此类操作,BackgroundWorker 类提供了方便的 溶液。
在单独的线程中运行代码
Thread yourThread = new System.Threading.Thread(delegate(){
//Your code
});
yourThread.Start();
更新主线程控件时要小心,需要使用 调用 ,例如在 WPF 应用中
Dispatcher.Invoke(new Action(delegate()
// your code that update main thread controls
{}));
int
doc_filescount = directory_info。GetFileSystemInfos("*.doc").长度;
IT 将在目录中生成(".doc"和".docx")文件计数