Eri*_* J. 11 asp.net-mvc asp.net-mvc-4
我使用中概述的方法从数据库生成一个非常大的.csv文件
它工作正常,达到一定程度.当导出的文件太大时,我会得到一个OutOfMemoryException.
如果我通过修改这样的代码来关闭输出缓冲:
protected override void WriteFile(System.Web.HttpResponseBase response)
{
response.BufferOutput = false; // <--- Added this
this.Content(response.OutputStream);
}
Run Code Online (Sandbox Code Playgroud)
文件下载完成.但是,它比启用输出缓冲时慢几个数量级(在localhost上测量缓冲为true/false的同一文件).
我知道这样做比较慢,但为什么它会慢慢相对爬行呢?我有什么办法可以提高处理速度吗?
UPDATE
也可以选择使用注释中建议的File(Stream stream,String contentType).但是,我不确定如何创建stream.数据是基于数据库查询动态组合的,而MemoryStream将耗尽连续的物理内存.欢迎提出建议.
更新2
在评论中建议,交替从数据库中读取并写入流会导致性能下降.我修改了代码以在单独的线程中执行流写入(使用生产者/消费者模式).性能没有明显差异.
我不知道ASP.NET和IIS正在做什么与输出流,但可能使用太小的块.挂在一个BufferedStream非常大的缓冲区,如4MB.
根据你的意见,它有效.现在,调低缓冲区大小以节省内存并使用较小的工作集.适合缓存.
作为主观评论,我很失望,这甚至是必要的.IIS应该自动使用正确的缓冲区,这对于TCP连接非常容易.
从OP编辑
这是从这个答案派生的代码
public ActionResult Export()
{
// Domain specific stuff here
return new FileGeneratingResult("MyFile.txt", "text/text",
stream => this.StreamExport(stream), false);
}
private void StreamExport(Stream stream)
{
using (BufferedStream bs = new BufferedStream(stream, 256*1024))
using (StreamWriter sw = new StreamWriter(bs))
foreach (var stuff in MyData())
{
sw.Write(stuff);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3828 次 |
| 最近记录: |