【问题标题】:How to fix out of memory error in a recursive method C#如何在递归方法 C# 中修复内存不足错误
【发布时间】:2023-04-09 05:11:01
【问题描述】:

我的问题是我有一个递归方法,它给出了一个在所有子文件夹中输入的路径,并将文件名和一些信息存储在数据库中。 在我使用一个包含 31000 个文件和很多子文件夹的文件夹之前,它工作得很好。我对该方法的参数是他正在工作的路径,作为数据库类的父路径和执行一些插入和选择的数据库类。我的问题是使用 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# visual-studio out-of-memory recursive-datastructures


【解决方案1】:

虽然递归很漂亮,有时需要更少的代码,但我建议你将它解包到循环中。 C# 有递归深度,然后超过了,运行时抛出错误。

但是如果重写代码不是一个选项,你can acquire bigger limit of recursion

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

【讨论】:

  • 感谢您的回答。我很想不重写它,但我认为这是最好的做法。我要保存代码,所以也许有人有其他想法,我要重写它。
【解决方案2】:

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

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

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

【讨论】:

  • 谢谢你的回答,但我需要获取子文件夹的信息。我进行了更改并仅对文件夹使用递归方法并将它们插入数据库。晚上晚些时候我会执行它,然后看看错误是否继续。
  • 我也在 DBContext 中做了一些更改,现在我在使用它后处理上下文。
猜你喜欢
  • 1970-01-01
  • 2021-09-17
  • 1970-01-01
  • 2016-02-02
  • 1970-01-01
  • 2019-04-18
  • 1970-01-01
  • 2013-12-12
  • 1970-01-01
相关资源
最近更新 更多