You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#处理37999条报表数据时抛出System.StackOverflowException求助

问题根因

你遇到的System.StackOverflowException核心原因是RetornaListaFilmes方法采用了递归调用的方式处理数据:

  • 每次循环处理完1条对应标题的记录后,只要dados列表不为空,就会直接调用return RetornaListaFilmes(dados, filmes, boolOnePaises)触发递归
  • 你有37999条数据,最坏情况下递归深度会达到数万级,远远超过.NET默认的1万左右的线程栈大小,直接触发栈溢出。

修复方案

1. 把递归逻辑改成迭代循环

直接把递归调用的逻辑替换成外层循环遍历dados列表,不需要每次调用方法本身,完全规避栈溢出风险,示例修改思路:
把原来的逻辑

foreach (var item in dados)
{
    // 处理单条记录逻辑
    dados.RemoveAll(x => x.titulo_original == item.titulo_original);
    if (dados.Count != 0)
    {
        return RetornaListaFilmes(dados, filmes, boolOnePaises);
    }
    else
    {
        break;
    }
}

替换为外层循环,直到dados为空:

while(dados.Count > 0)
{
    var item = dados[0];
    // 原来的单条记录处理逻辑保持不变
    dados.RemoveAll(x => x.titulo_original == item.titulo_original);
}

2. 额外性能优化点

你当前代码还有大量冗余判断和重复遍历逻辑,处理3万条数据效率很低,可以同步优化:

  • 所有filme.GroupRightCountries.Where(x => x.Direito == dadosDireito[i].direito).ToList().Count == 0的判断,可以改用Any()方法,不需要生成新列表,写法为!filme.GroupRightCountries.Any(x => x.Direito == dadosDireito[i].direito)
  • 同一个dadosDireito列表的重复遍历可以提前用GroupBy(x => x.direito)分组,不用每次循环都遍历整个列表查对应权限的国家
  • 可以提前对原始dados列表按titulo_original分组,不用每次处理完都调用RemoveAll删除元素,减少列表修改的性能开销

3. 异常处理修正

你当前代码的catch块写throw e;会清空原始异常的调用栈,不利于后续排查问题,直接改成throw;即可。

内容的提问来源于stack exchange,提问作者peterson benhame

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 01:57:04