问题
Right now I have an api that gets many results (800k) and it should parse and stream them as CSV. The (kind of) working code I have is this
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"
};
However this seems to put everything into memory, and store it using up 300 mb of memory. As i understand it, that happens in the foreach statement. Is there a way that i write the line, stream it, and then dispose of it from memory? My goal is to achieve something similar to this without using so much memory
I have also tried it this way, which works for one call, but if multiple api calls are made at the same time, there is weird behaviour
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));
}}
回答1:
You can write data directly to response body without need of putting it into a MemoryStream.
Asker edit: This is what I did
//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));
}
and it seems to work fine
来源:https://stackoverflow.com/questions/60054236/how-to-lower-memory-usage-in-filestreamresult-api