如何在.Net Core中的CSV导出期间处理大型列表

问题描述 投票:0回答:1

我有一个代码块,可以将一组记录(超过200k条记录)导出到CSV。在CSV写入期间分配了大内存块,由于某种原因,在返回CSV文件后垃圾收集器不会释放它。

我尝试过使用GC.Collect(),但我知道它不适用于大型堆对象。 GC.Collect()之后的GC.WaitForPendingFinalizers()也不会释放在此操作期间分配的所有内存。

using (var memoryStream = new MemoryStream())
{
  using (var streamWriter = new StreamWriter(memoryStream))
  using (var csvWriter = new CsvWriter(streamWriter))
  {
    csvWriter.Configuration.Delimiter =_configuration["Csv:Delimiter"];
    csvWriter.Configuration.CultureInfo = new CultureInfo(_configuration["Csv:Culture"]);

    if (!noClassMap)
    {
      csvWriter.Configuration.RegisterClassMap<U>();
    }

    //When writing 200,000 records, 500MB get allocated here, and never 
    freed. Details is an IQueryable that returns a 200,000 records 
    result. 
    csvWriter.WriteRecords(details);
  }

  return new SpreadsheetFile { FileBytes = memoryStream.ToArray(), FileName = fileName + DateTime.Now.ToShortDateString() + ".csv" };
}

我知道在写入内存流期间,所有对象列表都会在内存中分配。但是,在Web API返回实际的CSV后,是否应该释放它?我不确定这是否是预期的,或者这是否是某种内存泄漏(运行.NET Core 2.2.3)。

c# .net asp.net-core memory
1个回答
0
投票

返回新的SpreadsheetFile {FileBytes = memoryStream.ToArray()...

memoryStream.ToArray将所有数据存储到内存中的array中,并且引用它是由FileBytesSpreadsheetFile属性保留,这就是GC没有释放数据的原因。如果您认为SpreadsheetFile的实例不应该保留,请使用内存分析器查看将qazxswpoi实例保留在内存中的内容。

© www.soinside.com 2019 - 2024. All rights reserved.