Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何降低FileStreamResult api中的内存使用率_C#_Asp.net Core_.net Core_Entity Framework Core - Fatal编程技术网

C# 如何降低FileStreamResult api中的内存使用率

C# 如何降低FileStreamResult api中的内存使用率,c#,asp.net-core,.net-core,entity-framework-core,C#,Asp.net Core,.net Core,Entity Framework Core,现在我有一个api,它可以得到很多结果(800k),它应该将它们解析并流式处理为CSV。 我的工作代码是这样的 var query = context.address.AsNoTracking(); MemoryStream memoryStream = new MemoryStream(); StreamWriter writer = new StreamWriter(memoryStream);

现在我有一个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));

            }}

您可以直接将数据写入响应体,而无需将其放入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));
}

它似乎工作得很好

您可以直接将数据写入响应体,而无需将其放入内存流

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

//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));
}

而且它似乎工作正常

使用临时文件缓冲结果是否可以接受?因此,首先写入文件,而不是内存流,然后使用
Response.TransmitFile(filePath)
进行传输。我想这可能是一种解决方法,但仍然不能完全解决我的问题。我尝试使用yield return执行此操作,但这不会返回完整的csv文件,只返回许多行。问题是
MemoryStream
,而不是
FileStreamResult
。代码在返回之前缓存内存中的所有内容。一个简单快捷的解决方法是将数据导出到一个临时文本文件并返回该文件。您是否可以使用临时文件来缓冲结果?因此,首先写入文件,而不是内存流,然后使用
Response.TransmitFile(filePath)
进行传输。我想这可能是一种解决方法,但仍然不能完全解决我的问题。我尝试使用yield return执行此操作,但这不会返回完整的csv文件,只返回许多行。问题是
MemoryStream
,而不是
FileStreamResult
。代码在返回之前缓存内存中的所有内容。一个简单快捷的解决方法是将数据导出到一个临时文本文件并返回该文件,因为我已经尝试过了。Response.ContentType=“application/json”;Response.BodyWriter.WriteAsync(Encoding.UTF8.GetBytes(“ime,prezime,datarag”+Environment.NewLine));foreach(查询中的var row){Response.BodyWriter.WriteAsync(Encoding.UTF8.GetBytes(row));}这样尝试过,对于一个请求来说效果很好,但是对于多个请求,它似乎返回越来越多的数据,一个请求返回30mb(应该是这样的),然而,多个请求返回千兆字节的数据。这与异步方法有关吗?依我看,你应该“等待”异步写入。但即使如此,我也不确定异步是否是导致结果大小爆炸的原因。正如ben_a_adams所说。。如果使用Microsoft.AspNetCore.Http导入
,则可以使用
Response.WriteAsync(行)
直接传递字符串
是否返回Ok(查询)?,因为我已经尝试过了。Response.ContentType=“application/json”;Response.BodyWriter.WriteAsync(Encoding.UTF8.GetBytes(“ime,prezime,datarag”+Environment.NewLine));foreach(查询中的var row){Response.BodyWriter.WriteAsync(Encoding.UTF8.GetBytes(row));}这样尝试过,对于一个请求来说效果很好,但是对于多个请求,它似乎返回越来越多的数据,一个请求返回30mb(应该是这样的),然而,多个请求返回千兆字节的数据。这与异步方法有关吗?依我看,你应该“等待”异步写入。但即使如此,我也不确定异步是否是导致结果大小爆炸的原因。正如ben_a_adams所说。。如果使用Microsoft.AspNetCore.Http导入
,则可以使用
Response.WriteAsync(行)
直接传递字符串