保存时内存不足异常实体框架

本文关键字:实体 框架 异常 内存不足 保存 | 更新日期: 2023-09-27 18:30:17

我在实体框架中循环访问许多不同的对象,获取一些相关数据并保存这些数据。我正在为每个项目打开一个新线程,因为在该方法中完成工作需要一段时间。但是,我在循环中出现了几千个项目的内存异常。我试图找出此问题发生的位置以及如何保持多线程功能,但修复错误。任何帮助将不胜感激。谢谢。

    foreach (var prod in products)
    {
        try
        {
            new Thread(() =>
            {
                ParsePage(prod);
            }).Start();

            counter++;
            Console.WriteLine(counter);
        }
        catch (Exception ex)
        {
            string message = ex.Message;
        }
    }
    public void ParsePage(Product p)
    {
        //New Repository
        IDataRepository repo = new DataRepository();
        //Grab related page report
        PageReport pr = repo.PageReports.Where(c => c.ThePageType == "Product").FirstOrDefault(c => c.ThePageTypeID == p.ProductID);
        //Do some stuff
        //Save
        repo.SavePageReport(pr);
    }

保存时内存不足异常实体框架

内存可能不足,因为每个线程的默认堆栈大小为 1 MB。 2000 个启动的线程意味着 2 GB 的堆栈,这可能是系统上的最大值:

Windows 上应用程序的内存限制*

32 位

  • 静态数据 - 2GB
  • 动态数据 - 2GB
  • 堆栈数据 - 1GB(堆栈大小由链接器设置,默认值为 1MB。 可以使用链接器属性系统>堆栈保留大小)增加此值)

请注意,在 32 位 Windows 上,所有类型的数据的总和必须小于 2GB。 由于Windows本身使用的空间,实际限制约为1.75GB

64 位

  • 静态数据 - 2GB
  • 动态数据 - 8TB
  • 堆栈数据 - 1GB(堆栈大小由链接器设置,默认值为 1MB。 可以使用链接器属性系统>堆栈保留大小)增加此值)

另请参阅Raymond Chen的这篇文章和这个stackoverflow问题以获取更多信息。

正如 KroaX 所说,较新的任务和较旧的线程池库旨在处理此类情况。 它们在线程和任务之间提供了额外的抽象级别,使您可以轻松创建数千个轻量级任务,这些任务将在线程可用时分配给线程。

如果对整个操作使用相同的 DbContext,则其缓存可能会导致内存不足错误。在解析和存储来自 XML 文件的大量数据时,我遇到了类似的情况。

您应该按照 dbc 的建议使您的存储库是一次性的,然后将其包装在 using 子句中:

public void ParsePage(Product p)
{
    using (var repo = new DataRepository())
    {
        //Grab related page report
        PageReport pr = repo.PageReports.Where(c => c.ThePageType == "Product").FirstOrDefault(c => c.ThePageTypeID == p.ProductID);
        //Do some stuff
        //Save
        repo.SavePageReport(pr);
    }
}

有关如何实现一次性模式的信息,请参阅此处