这是一个非常简单的示例,我如何将Stream
返回到ASP.NET MVC:
public ActionResult DownloadData(...)
{
using(var lib = new SomeLibrary())
{
// do some stuff...
var stream = new MemoryStream();
lib.SaveAs(stream);
stream.Position = 0;
return File(stream, "contenttype", "filename");
}
}
问题是MemoryStream
将在大型堆对象区域中分配,在32位系统上它会很快导致OutOfMemoryException
,因为RAM碎片会阻止分配大内存块,即使有足够的记忆力。在64位系统上,这种方法也很慢。
我想要的只是返回一个流,类似于
public ActionResult DownloadData(...)
{
using(var lib = new SomeLibrary())
{
// do some stuff...
return File(lib.Stream, "contenttype", "filename");
}
}
然而,在我的数据返回之前,using
语句将调用.Dispose()
。如果我完全删除using
语句,那么库将锁定资源,直到垃圾收集器清理内存。
我认为最好的解决方案是使用只复制源流的通用Stream
并在最后调用.Dispose()
:
public ActionResult DownloadData(...)
{
var lib = new SomeLibrary()
try
{
// do some stuff...
var stream = new CopyStream(lib.Stream, lib);
return File(stream, "contenttype", "filename");
}
catch(Exception)
{
lib.Dispose();
throw;
}
}
通用流应在关闭后调用.Dispose()
以获取第二个参数lib
。
在.NET或NuGet中是否存在此类Stream
的现有实现?
答案 0 :(得分:1)
也许我不明白你需要什么,但在你的情况下,你不需要自己处理流(使用显式的Dispose()调用或使用使用关键字)。< / p>
来自ASP MVC控制器的File帮助程序方法旨在返回流:它创建一个FileStreamResult,负责处理封装的流,并在其工作完成时执行。
在这个主题上,您可以在here找到更好更详细的Darin Dimitrov答案。