【发布时间】:2019-10-20 20:15:13
【问题描述】:
在互联网上搜索了几个小时后,我不知道如何解决我的 ASP.NET Core 2.x 问题。
我正在动态生成 CSV(可能需要几分钟),然后尝试将其发送回客户端。在我开始发送响应之前,许多客户端都超时了,所以我试图将文件流回给他们(立即响应 200)并异步写入流。以前在 ASP 中使用 PushStreamContent 似乎可以做到这一点,但我不确定如何构造我的代码,以便异步完成 CSV 生成并立即返回 HTTP 响应。
[HttpGet("csv")]
public async Task<FileStreamResult> GetCSV(long id)
{
// this stage can take 2+ mins, which obviously blocks the response
var data = await GetData(id);
var records = _csvGenerator.GenerateRecords(data);
// using the CsvHelper Nuget package
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
var csv = new CsvWriter(writer);
csv.WriteRecords(stream, records);
await writer.FlushAsync();
return new FileStreamResult(stream, new MediaTypeHeaderValue("text/csv))
{
FileDownloadName = "results.csv"
};
}
如果您向此控制器方法发出请求,则在整个 CSV 完成生成并最终获得响应之前,您将一无所获,此时大多数客户端请求已超时。
我尝试将 CSV 生成代码包装在 Task.Run() 中,但这也对我的问题没有帮助。
【问题讨论】:
-
您可以使用Response.Body 直接写入输出流而不是MemoryStream。不过,这对
await GetData();没有任何作用。这与流式传输或 CSV 生成无关。 -
这很公平,但是您能建议一种方法来重组代码以实现这一点吗?旧的
PushStreamContent类用于让您注册一个回调,该回调将在初始 200 响应后执行。 -
要写入流,只需使用
Response.Body,例如new StreamWriter(Response.Body)。但是,这不会使慢查询运行得更快,并且您仍然会超时。GetData做了什么,为什么需要 2 分钟?修复错误查询可能比后台生成 CSV 文件更有效(也更快)。 -
谢谢,我会试试的。我正在关注本教程,该教程展示了如何立即响应 200,然后写入输出流:blog.stephencleary.com/2016/10/async-pushstreamcontent.html
-
它加载了多少数据?如果加载 100 行需要 2 分钟,那么编写它的人应该修复它。
标签: c# asp.net-mvc asp.net-core .net-core csvhelper