Search code examples
c#using

RemoteFileInfo Fails with Using statement


I am having a problem with a pretty simply program. We started off with this bit of working code:

RemoteFileInfo result = new RemoteFileInfo();

string filePath = System.IO.Path.Combine(ConfigurationManager.AppSettings["OmnitureSPDir"], request.FileName);
System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);

// check if exists
if (!fileInfo.Exists)
    throw new System.IO.FileNotFoundException("File not found",
                      request.FileName);

// open stream
System.IO.FileStream stream = new System.IO.FileStream(filePath,
          System.IO.FileMode.Open, System.IO.FileAccess.Read);

// return result 
result.FileName = request.FileName;
result.Length = fileInfo.Length;
result.FileByteStream = stream;

return result;

This takes in a parameter called "request" that contains the filename, we check to see if the file exists, and if so, we stream the file.

Well, after going through the microsoft code analysis in Visual Studio, and noticing that there was no dispose(), I "solved" the issue by wrapping it in a using statement:

using (RemoteFileInfo result = new RemoteFileInfo()) {

    string filePath = System.IO.Path.Combine(ConfigurationManager.AppSettings["OmnitureSPDir"], request.FileName);
    System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);

    // check if exists
    if (!fileInfo.Exists)
        throw new System.IO.FileNotFoundException("File not found",
                          request.FileName);

    // open stream
    System.IO.FileStream stream = new System.IO.FileStream(filePath,
              System.IO.FileMode.Open, System.IO.FileAccess.Read);

    // return result 
    result.FileName = request.FileName;
    result.Length = fileInfo.Length;
    result.FileByteStream = stream;

    return result;
}

After running this code, we found that the file no longer would stream, but would error with:

Value cannot be null.
Parameter name: FileByteStream

Taking the Using() statement out, fixed the problem, but I don't understand why. I thought I was doing a good thing, by adding in the code. I would like to understand what I did wrong, so that I don't repeat it and can properly code this method.

Here is the definition for RemoteFileInfo

public class RemoteFileInfo : IDisposable
{
    [MessageHeader(MustUnderstand = true)]
    public string FileName;

    [MessageHeader(MustUnderstand = true)]
    public long Length;

    [MessageBodyMember(Order = 1)]
    public System.IO.Stream FileByteStream;

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);

    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing && FileByteStream != null)
            {
                FileByteStream.Close();
                FileByteStream = null;
            }

    } 
}

Solution

  • If you are returning an object that implements IDisposable, then you cannot Dispose it. That has to be up to the caller.