C# 对象太多导致内存不足异常

C# 对象太多导致内存不足异常,c#,asp.net,.net,C#,Asp.net,.net,快速概述我的情况: 我得到了按字符数分割的文本文件,我正在开发一个应用程序,根据解析的文件将每一行分割成一个模型列表。例如,300行长的Persons文本文件将创建自定义模型“Person”的列表。列表中的每个项目都是文件中的一行。这是通过以下方式实现的: private static List<Person> InitializePeople(DataManager dm, string filePath) { List<Person>

快速概述我的情况: 我得到了按字符数分割的文本文件,我正在开发一个应用程序,根据解析的文件将每一行分割成一个模型列表。例如,300行长的Persons文本文件将创建自定义模型“Person”的列表。列表中的每个项目都是文件中的一行。这是通过以下方式实现的:

    private static List<Person> InitializePeople(DataManager dm, string filePath)
    {
        List<Person> people= new List<Person>();
            //Get lines from file to loop through
            foreach (var line in dm.GetDataLinesFromFile(filePath).ToList())
            {
               Person person = new Person();
               //This splits out the character counted split line 
               //into the models format and adds it to a list
               people.Add((Person)dm.GetFormattedData(person, new FormatManger(), line));
            }
        return people;
     }
private static List InitializePeople(DataManager dm,string filePath)
{
列表人员=新列表();
//从文件中获取要循环的行
foreach(dm.GetDataLinesFromFile(filePath.ToList()中的var行)
{
Person=新人();
//这将分割出字符计数的分割线
//并将其添加到列表中
添加((Person)dm.GetFormattedData(Person,new FormattManger(),line));
}
还人,;
}

在我得到一个数百万行长的文件之前,这一切都很正常。正如您所看到的,我在循环中提交了一个厚颜无耻的NONO,在循环中,我每次循环时都实例化一个新对象。我相信这就是我的问题所在,当无数个对象被实例化时,它开始为内存而挣扎。有什么更好的方法?还有其他更有效的方法吗?感谢您的帮助。

人的名单越来越大,无法保存在内存中。我建议分块做,在处理下一块之前先处理每一块。 如果您将方法签名更改为接受块大小和位置
私有静态列表InitializePeople(DataManager dm、string filePath、int chunkSize、out int position)
您可以实现这一点。这样,您就不必读取整个文件,只需跳到某一行,然后读取所需数量的记录

伪代码如下所示:

var position = 0
var people = []
while (count (people = InitializePeople(dataManager, file, 250, out position) > 0)
    do something with people
    position += count people
不要具体化数据(即避免
ToList()
ToArray()
等)仅使用IEnumerable

首先,检查
dm.GetFormattedData
实现,它应该是

  public IEnumerable<String> GetDataLinesFromFile(filePath) {
    // Check that neither ReadAllLines nor ReadAllText is there
    // Check absence of ToList() and ToArray() as well
    return File
      .ReadLines(filePath) // the only possible way of reading file
      .Select(...) // possible, but not necessary part
      .Where(...); // possible, but not necessary part
  }
所以在Linq的帮助下,你可以有很大的灵活性,例如

  File.WriteAllLines(@"C:\MyFile.txt", InitializePeople(dm, @"C:\People.txt")
   .Where(people => people.LastName == "Smith")
   .Select(people => String.Format("{0} is {1} years old", people.FirstName, people.Age));

对不要试图创建数以百万计的对象。您可能应该使用数据库。是否需要同时将它们全部存储在内存中?如果没有,请使用
IEnumerable File.ReadLines()
yield return
,省略
ToList()
。问题不在于在循环中创建对象,而在于维护的列表将根据大小而增长。顺便问一下,你对列表做了什么?我把这些数据放在列表中是因为我想让我对它做一些灵活的处理,例如,把它放在一个文件中,放在一个数据库中,也许为了我没有看到的其他目的而过滤它。我不想假设这些数据会进入一个新的阶段DB@CodeCaster谢谢你,但你能再解释一下你的意思吗?我不确定我是否理解,谢谢你,我会试一试,让你知道它是怎么走的。我试着走这条路,发现德米特里的反应更优雅一点。再次感谢你的帮助!我同意,他的解决方案更优雅。很高兴你解决了这个问题。谢谢你,我会在几天前给你这个,你能解释一下为什么物化数据不好吗?@Srb1313711:一般情况下,它不坏,因为物化在内存中创建了数百万项的列表。我建议流媒体:一个项目接着一个项目处理。谢谢你,这非常有帮助,看起来它解决了我的问题!
  File.WriteAllLines(@"C:\MyFile.txt", InitializePeople(dm, @"C:\People.txt")
   .Where(people => people.LastName == "Smith")
   .Select(people => String.Format("{0} is {1} years old", people.FirstName, people.Age));