1

这是一个非常简单的示例,我如何将 a 返回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

Stream在 .NET 或 NuGet 中是否有任何现有的实现?

4

1 回答 1

1

也许我不完全了解您需要什么,但在您的情况下,无需自己处理流(使用显式 Dispose() 调用或using关键字)。

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

关于这个主题,您可以在此处找到 Darin Dimitrov 的更好、更详细的答案。

于 2013-10-12T17:41:31.633 回答