保存时内存不足异常实体框架
本文关键字:实体 框架 异常 内存不足 保存 | 更新日期: 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);
}
}
有关如何实现一次性模式的信息,请参阅此处