views:

43

answers:

1

Hi folks,

What's the proper way of disposing resources when a method in the controller returns filestream or file or filecontentresult objects ?

For ex when doing something like below:

   using CrystalDecisions.CrystalReports.Engine;

public ActionResult Report()
{
    ReportClass rptH = new ReportClass();
    rptH.FileName = Server.MapPath("[reportName].rpt");
    rptH.Load();
    rptH.SetDataSource([datatable]);
    Stream stream = rptH.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
    return File(stream, "application/pdf");   
}

TIA

+2  A: 

A FileStreamResult (which is what is created) wraps the stream in a using statement when WriteFile is called during result execution. This will close and dispose of the stream. Depending on the type of stream created it may actually cause an error to either close or wrap the usage in a using statement in the controller action.

tvanfosson
Curiously, it wraps the `FileStream` type: `using (FileStream)`. What in the world is going on there? Is `Type` disposable?
Jeff Sternal
@Jeff - actually `FileStream` is a property that just happens to have the same name as the FileStream class.
tvanfosson
Oh right, what in the world was I thinking. It's not typeof(FileStream) - and the property is about 7 lines away. Time to get more cofee. D:
Jeff Sternal
@tv - Are you saying this is done internally, so we don't have to explicity use 'using' statement?
SoftwareGeek
@BhejaFry - yes, it will close the stream for you. In fact, since the write doesn't happen until well after the return, I think it's best practice **NOT** to close the stream in your code, either explicitly or with a using statement. If you want to handle the close explicitly, you should use an override that takes a byte array rather than a stream and get the bytes from the stream yourself.
tvanfosson