首页 > 解决方案 > C# 代码需要很长时间才能运行。有没有办法让它更快完成?

问题描述

我需要一些帮助。如果您在我的代码中输入一个目录,它会进入该目录中的每个文件夹并获取每个文件。这样,我设法通过使用代码绕过“AccessDeniedException”,但如果目录是一个,其中包含大量数据和文件夹(例如:C:/),它只需要很多时间。

我真的不知道如何多线程,我在互联网上找不到任何帮助。有没有办法通过多线程使代码运行得更快?或者是否可以要求代码使用更多的内存或核心?我真的不知道并且可以使用建议

我的代码进入每个子目录中的每个文件:

public static List<string> Files = new List<string>();
public static List<string> Exceptions = new List<string>();

public MainWindow()
{
    InitializeComponent();
}

private static void GetFilesRecursively(string Directory)
{
    try
    {
         foreach (string A in Directory.GetDirectories(Directory))
             GetFilesRecursively(A);

         foreach (string B in Directory.GetFiles(Directory))
             AddtoList(B);

    } catch (System.Exception ex) { Exceptions.Add(ex.ToString()); }
}

private static void AddtoList(string Result)
{
    Files.Add(Result);
}

private void Btn_Click(object sender, RoutedEventArgs e)
{
    GetFilesRecursively(Textbox1.Text);
    
    foreach(string C in Files)
       Textbox2.Text += $"{C} \n";
}

标签: c#multithreadingrecursionsubdirectory

解决方案


您不需要递归来避免无法访问的文件。您可以使用接受EnumerationOptions参数的EnumerateFiles重载并将EnumerationOptions.IgnoreInaccessible设置为:true

var options=new EnumerationOptions 
            {
                IgnoreInaccessible=true,
                RecurseSubdirectories=true
            };
var files=Directory.EnumerateFiles(somePath,"*",options);

附加文件路径的循环也非常昂贵。它不仅会在每次迭代时创建一个新的临时字符串,还会强制 UI 重绘。您可以通过创建单个字符串来提高速度和内存使用率(由于垃圾收集也会影响性能),例如 withString.Join或 a StringBuilder

var text=String.Join("\n",files);
Textbox2.Text=text;

String.Join在内部使用 StringBuilder ,其内部缓冲区每次满时都会重新分配。必须对先前的缓冲区进行垃圾收集。一次甚至可以通过使用StringBuilder具有特定容量的 a 来避免这种情况。即使是粗略的估计也可以显着减少重新分配:

var builder=new StringBuilder(4096);
foreach(var file in files)
{
    builder.AppendLine(file);
}

推荐阅读