gpt4 book ai didi

c# - yield return - 内存优化

转载 作者:太空宇宙 更新时间:2023-11-03 20:00:25 26 4
gpt4 key购买 nike

还有一个关于yield return的问题

所以我需要远程执行不同的SQL脚本。脚本在 TFS 中,所以我自动从 TFS 获取它们,并且该过程遍历所有文件,读取它们在内存中的内容并将内容发送到远程 SQL 服务器。

到目前为止,该过程完美无缺。但现在一些脚本将包含批量插入,将脚本的大小增加到 500,000 MB 或更多。

所以我构建了代码“思考”,我曾经在内存中读取文件的内容,但现在我有了第二个想法。

这就是我所拥有的(过度简化):

    public IEnumerable<SqlScriptSummary> Find(string scriptsPath)
{
if (!Directory.Exists(scriptsPath))
{
throw new DirectoryNotFoundException(scriptsPath);
}

var path = new DirectoryInfo(scriptsPath);

return path.EnumerateFiles("*.sql", SearchOption.TopDirectoryOnly)
.Select(x =>
{
var script = new SqlScriptSummary
{
Name = x.Name,
FullName = x.FullName,
Content = File.ReadAllText(x.FullName, Encoding.Default)
};

return script;
});
}

....

public void ExecuteScripts(string scriptsPath)
{
foreach (var script in Find(scriptsPath))
{
_scriptRunner.Run(script.Content);
}
}

我的理解是 EnumerateFilesyield return 一次每个文件,所以这就是让我“认为”我正在加载的原因内存中一次一个文件。

但是...

一旦我迭代它们,在 ExecuteScripts 方法中 script 变量会发生什么 foreach 超出范围后循环?那是处置了吗?还是留在内存中?

  • 如果它保留在内存中,这意味着即使我使用迭代器并在内部使用 yield return 当我遍历它们时它们仍然在内存中,对吗?所以最后就像使用 ToList 只是延迟执行,对吗?

  • 如果 script 变量在超出范围时被释放,那么我想我会没事的

我如何重新设计代码以优化内存消耗,例如强制一次只将脚本的内容加载到内存中

其他问题:

  • 我如何测试(单元/集成测试)我一次只在内存中加载一个脚本?

  • 如何测试(单元/集成测试)每个脚本是否从内存中释放?

最佳答案

Once that I'm iterating them, what happens with the script variable used in the foreach loop after it goes out of scope? Is that disposed? or does it remain in memory?

如果您的意思是在 ExecuteScripts 方法中 - 没有什么可处理的,除非 SqlScriptSummary 实现了 IDisposable,这似乎不太可能。但是,这里有两个不同的地方:

  • script 变量在 foreach 循环后超出范围,不能充当 GC 根
  • script 变量引用的每个对象都将有资格在没有其他对象引用它时进行垃圾回收...包括下一次迭代的 script。<

所以是的,基本上这应该是绝对没问题的。您将一次加载一个文件,就 GC 无法收集的对象而言,我看不出内存中一次有多个文件内容的任何原因。 (GC 本身是惰性的,因此不太可能恰好一次在内存中有一个脚本,但您不必担心那方面的事情,因为您的代码确保它一次不会保留对多个脚本的实时引用。)

测试您是否一次只加载一个脚本的方法是尝试使用大型脚本的大型目录(实际上不执行任何操作)。如果您可以处理的脚本多于您的内存,那很好:)

关于c# - yield return - 内存优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29172975/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com