Reputation: 129
I've written up some fairly quick-ish code and ever since changing it to "SearchOption.AllDirectories", it takes a whole minute to even just load the form/application.
Is there something I can do to make this application run faster on load? Any help/information would be appreciated.
Thanks.
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;
}
Upvotes: 1
Views: 1462
Reputation: 1
int doc_filescount = directory_info.GetFileSystemInfos("*.doc").Length;
IT will produce both (".doc" and ".docx") files count in a directory
Upvotes: -1
Reputation: 111820
This:
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));
is totally w r o n g.
Each EnumerateFiles
will rescan all the subdirectories for a certain type of file. Even worse: you are counting how many files you have in total of that types, but what you want is "is there any file of that extensions"? So after finding the first file .pdf
you could stop.
You should search for "*" and then filter by the extensions you want, stopping at the first file found.
This
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));
}
is probably better.
And are you sure you have to search in subfolders? Because SearchOption.AllDirectories
will search in subfolders, and not only in the given folder.
Upvotes: 5
Reputation: 1626
Run your code in a separate thread
Thread yourThread = new System.Threading.Thread(delegate(){
//Your code
});
yourThread.Start();
Be care when updating main thread controls, you need to use Invoke , for example in a WPF app
Dispatcher.Invoke(new Action(delegate()
// your code that update main thread controls
{}));
Upvotes: 0
Reputation: 166346
Why dont you just load the root directory on form load, and then load each sub node once the user expands that node.
Further to that, why dont you look at using BackgroundWorker Class to make the Userinterface more interactive?
The BackgroundWorker class allows you to run an operation on a separate, dedicated thread. Time-consuming operations like downloads and database transactions can cause your user interface (UI) to seem as though it has stopped responding while they are running. When you want a responsive UI and you are faced with long delays associated with such operations, the BackgroundWorker class provides a convenient solution.
Upvotes: 0