Search code examples
c#asp.netfile-uploadwebformsdispose

Should I dispose FileUpload.PostedFile.InputStream?


Is this code needed, or because the UnLoad event of the page disposes all controls on page anyway there's no point in writing such code:

fu.PostedFile.InputStream.Flush();
fu.PostedFile.InputStream.Close();
fu.FileContent.Dispose();    

I'm asking because on examples from msdn I see that they write code like

FileUpload1.SaveAs(savePath);

but don't ever bother to dispose the stream afterwards, but on the hand I see some people do explicitly dispose the input stream after saving?


Solution

  • Official guidance suggests that there is no need to dispose this stream, as it will be disposed when request processing ends:

    Server resources that are allocated to buffer the uploaded file will be destroyed when the request ends. To save a durable copy of the file, use the SaveAs method.

    To back this up I also did a bit of code digging through the sources. Turns out that neither FileUpload nor HttpPostedFile are responsible for disposing this stream. In fact they themselves do not hold any resources at all, and just provide an interface to access parts of the request.

    HttpRequest does some disposal. But not all disposable objects are being disposed. Here is its Dispose:

    /*
     *  Cleanup code
     */
    internal void Dispose() {
        if (_serverVariables != null)
            _serverVariables.Dispose();  // disconnect from request
    
        if (_rawContent != null)
            _rawContent.Dispose();  // remove temp file with uploaded content
    }
    

    What is not disposed however is the collection HttpRequest.Files, which the upload controls interface. To fill this collection up with data every posted file is wrapped into an HttpPostedFile object, and an HttpInputStream is created for each. This stream object holds the reference to the whole data (see rawContent above) and knows about offset and length of relevant file part. It is worth noting that HttpInputStream implements IDisposable, however I wasn't able to find the code that disposes these stream objects.

    To sum it up:

    1. Upload controls do not dispose the stream
    2. Request or HttpContext do not dispose the stream either
    3. However Request disposes the underlying data

    So it looks like the idea here is that when request processing is finished, references to the relevant data will be dropped and it will be disposed. So it won't hurt to manually dispose the stream you've used, but it is also not necessary.