繁体   English   中英

关闭后可以为另一个对象调用Dispose()方法的通用Stream

[英]Generic Stream that can call Dispose() method for another object after closing

这是一个非常简单的示例,如何将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位系统上,由于RAM碎片,即使有足够的内存,这也会阻止分配大的内存块,因此很快就会导致OutOfMemoryException 在64位系统上,此方法也很慢。

我想要的只是返回一个流,类似于此

public ActionResult DownloadData(...)
{
    using(var lib = new SomeLibrary())
    {
        // do some stuff...
        return File(lib.Stream, "contenttype", "filename");
    }
}

但是,然后using语句将在返回我的数据之前调用.Dispose() 如果我完全删除了using语句,那么该库将锁定资源,直到垃圾回收器清理内存为止。

我认为最好的解决方案是使用仅复制源流并在最后调用.Dispose()的通用Stream

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;
    }
}

通用流在关闭后应为第二个参数lib调用.Dispose()

.NET或NuGet中是否存在此类Stream现有实现?

也许我不确定您到底需要什么,但是在您的情况下,不需要自己处理流(使用显式Dispose()调用或using关键字)。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM