首页 > 解决方案 > 如何降低 FileStreamResult api 中的内存使用率

问题描述

现在我有一个 api 可以得到很多结果(800k),它应该将它们解析并流式传输为 CSV。我拥有的(某种)工作代码是这样的

            var query = context.address.AsNoTracking();

            MemoryStream memoryStream = new MemoryStream();
            StreamWriter writer = new StreamWriter(memoryStream);

              foreach (var row in query)
            {
                writer.WriteLine(row.Name+","+row.Surname+","+row.BirthDate);

            }

            writer.Flush();                                 
            memoryStream.Seek(0, SeekOrigin.Begin);
            return new FileStreamResult(memoryStream, "application/octet-stream")
            {
                FileDownloadName = "DataFile.csv"
            };

但是,这似乎将所有内容都放入内存,并使用 300 mb 的内存进行存储。据我了解,这发生在 foreach 语句中。有没有办法让我写下这条线,流式传输它,然后从内存中处理它?我的目标是在不使用太多内存的情况下实现类似的目标

我也试过这种方式,一次调用有效,但是如果同时进行多个api调用,就会出现奇怪的行为

 public async Task makeDif()
    {




            //var query = context.Adresar.AsNoTracking();
        var query = context.Adresar.Select(x => string.Join(",", x.Ime, x.Prezime, x.Datarag + Environment.NewLine)).AsNoTracking();
        Response.ContentType = "application/json";
        Response.BodyWriter.WriteAsync(Encoding.UTF8.GetBytes("ime,prezime,datarag" + Environment.NewLine)); 
        foreach (var row in query)
                {
               await Response.BodyWriter.WriteAsync(Encoding.UTF8.GetBytes(row));

            }}

标签: c#asp.net-core.net-coreentity-framework-core

解决方案


您可以直接将数据写入响应主体,而无需将其放入 MemoryStream。

提问者编辑:这就是我所做的

//var query = context.Adresar.AsNoTracking();
var query = context.Adresar.Select(x => string.Join(",", x.Ime, x.Prezime, x.Datarag + Environment.NewLine)).AsNoTracking();
Response.ContentType = "application/json";
Response.BodyWriter.WriteAsync(Encoding.UTF8.GetBytes("ime,prezime,datarag" + Environment.NewLine)); 
foreach (var row in query)
{
    await Response.BodyWriter.WriteAsync(Encoding.UTF8.GetBytes(row));
}

它似乎工作正常


推荐阅读