如何修复递归方法 C# 中的内存不足错误

How to fix out of memory error in a recursive method C#

我的问题是我有一个递归方法,该方法给出了它在所有子文件夹中输入的路径,并将文件名和一些信息存储在数据库中。 在我使用一个包含 31000 个文件和许多子文件夹的文件夹之前,它工作正常。我对该方法的参数是他正在工作的路径,父路径作为数据库 class 和数据库 class 来执行一些插入和选择。我的问题是使用 ref 关键字是否有助于解决内存问题?

抱歉,如果有关于此的文章。我什么也没找到。

public void ManageFiles(string path, Table Father, DataBaseHandlerClass DB)
{
    try
    {
        log.Info("---------------------------Inicio Pasta " + path + "--------------------------");
        DirectoryInfo d = new DirectoryInfo(path);
        DirectoryInfo[] Dirs = d.GetDirectories();
        int hashCode = path.GetHashCode();
        IFB_FilePath FilePath = DB.InsertOrUpdatePath(hashCode, path, Father == null ? null : (int?)Father.ID);

        foreach (var newPath in Dirs)
        {
            ManageFiles(newPath.FullName, FilePath, DB);
        }

        List<string> ext = DB.GetExtensionsToSearch();

        FileInfo[] Files = d.GetFiles("*.*").Where(s => ext.Contains(s.Extension.ToLower())).ToArray();
        var watch = System.Diagnostics.Stopwatch.StartNew();
        foreach (FileInfo file in Files)
        {
            watch = System.Diagnostics.Stopwatch.StartNew();
            FileTable Ficheiro = DB.InsertOrUpdateFile(file, FilePath);
            if (Ficheiro.ID_Extension_Group == 1 && !Ficheiro.Metadata.Any())
            {
                CreateFileMetadata(DB, Ficheiro);
            }
            else
            {
                if (Ficheiro.ID_Extension_Group == 1 && Ficheiro.TakenDate == null)
                {
                    UpdateTakenDate(DB, Ficheiro);
                }
            }

            watch.Stop();

            log.Info("Tempo em ms: " + watch.ElapsedMilliseconds + " Ficheiro " + file.Name);
        }
        log.Info("---------------------------Fim Pasta " + path + "--------------------------");
    }
    catch (Exception Ex)
    {
        log.Error(Ex);
    }
}

虽然递归很漂亮而且有时需要的代码更少,但我建议您将其展开为循环。 C# 有递归深度,然后它超出了,运行时抛出错误。

但如果重写代码不是一种选择,您 can acquire bigger limit of recursion.

正如 this 网站所说,C# 中的嵌套可以像 14250 调用一样大。所以在你的情况下,调用函数 31000 次超过了这个限制。

我认为您应该首先将以下几行移到 ManageFiles 函数之外:

 DirectoryInfo d = new DirectoryInfo(path);
 DirectoryInfo[] Dirs = d.GetDirectories();
 int hashCode = path.GetHashCode();

这是因为您在每次调用该函数时都会创建一个新的 DirectoryInfo 对象和目录集合。这是我要进行的第一个更改,因为它肯定会对内存产生影响。