1

Here is a very simple example how I can return a Stream to 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");
    }
}

The problem is that MemoryStream will be allocated in large heap object area and on 32 bit system it will cause OutOfMemoryException quite soon because of RAM fragmentation that will prevent allocation of a large memory block even if there is enough memory. On 64 bit systems this method is also quite slow.

What I want is just return a stream, similar to this

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

However then the using statement will call .Dispose() before my data is returned. If I remove the using statement completely, then the library will lock resources until garbage collector clean up memory.

I think the best solution will be to use a generic Stream that just copy the source stream and call .Dispose() at the end:

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

The generic stream should call .Dispose() for the second parameter lib after closing.

Is there any existing implementation for such a Stream in .NET or NuGet?

BartoszKP
  • 34,786
  • 15
  • 102
  • 130
user1224129
  • 2,759
  • 3
  • 27
  • 29
  • It is entirely unclear why you look for something custom. The Stream class already inherits IDisposable and implements the disposable pattern. You should of course use the *using* keyword to get it disposed, like you do with any stream. It otherwise has no effect whatsoever on memory usage, that's managed by the garbage collector, not your program. – Hans Passant Oct 12 '13 at 14:48

1 Answers1

1

Maybe i did not understand exactly what you need but in your case, there is no need to dispose the stream by yourself (with an explicit Dispose() call or with the using keyword).

The File helper method coming from ASP MVC controller is designed to return streams : It creates a FileStreamResult that is in charge of disposing the encapsulated stream and will do it when its job is done.

On this topic, you can find a far better and more detailed answer of Darin Dimitrov in here.

Community
  • 1
  • 1
AirL
  • 1,887
  • 2
  • 17
  • 17