Generic Stream,可以在关闭后调用另一个对象的Dispose()方法

时间:2013-10-12 14:11:40

标签: c# stream

这是一个非常简单的示例,我如何将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的现有实现?

1 个答案:

答案 0 :(得分:1)

也许我不明白你需要什么,但在你的情况下,你不需要自己处理流(使用显式的Dispose()调用或使用使用关键字)。< / p>

来自ASP MVC控制器的File帮助程序方法旨在返回流:它创建一个FileStreamResult,负责处理封装的流,并在其工作完成时执行。

在这个主题上,您可以在here找到更好更详细的Darin Dimitrov答案。