Search code examples
c#.netusing-statement

Understanding the using statement


I have written two codes:

code block 1:

Stream dataStream;
using (var response = (HttpWebResponse)req.GetResponse())
{
    dataStream = response.GetResponseStream();
}

//Open the stream using a StreamReader for easy access
using (var reader = new StreamReader(dataStream))
{
    data = reader.ReadToEnd();
}

code block 2:

Stream dataStream;
using (var response = (HttpWebResponse)req.GetResponse())
{
    dataStream = response.GetResponseStream();

    //Open the stream using a StreamReader for easy access
    using (var reader = new StreamReader(dataStream))
    {
        data = reader.ReadToEnd();
    }
}

Code block 1 is throwing error: stream is not reachable.
While progmatically i think both code will work same.
I added using block in to whole statment in code block 2 and it's working.
But I'm confused why is it throwing error in code block 1


Solution

  • Because post compilation (in IL), your code gets converted to the following

    Code Block: 1

                HttpWebResponse response=null;
                Stream dataStream;
                try
                {
                    response = (HttpWebResponse) req.GetResponse();
                    dataStream = response.GetResponseStream();
                }
                finally
                {
                    if(response!=null)
                        ((IDisposable)response).Dispose();
                }
    
                StreamReader reader = null;
                try
                {
                    //DataStream is accessed AFTER response object is disposed 
                    reader = new StreamReader(dataStream);
                    data = reader.ReadToEnd();
                }
                finally
                {
                    if(reader!=null)
                        reader.Dispose();
                }
    

    Code Block: 2

      HttpWebResponse response=null;
                Stream dataStream;
                try
                {
                    response = (HttpWebResponse) req.GetResponse();
                    dataStream = response.GetResponseStream();
    
                    StreamReader reader = null;
                    try
                    {
                        //DataStream is accessed while response object is alive, and connected (not disposed)
                        reader = new StreamReader(dataStream);
                        data = reader.ReadToEnd();
                    }
                    finally
                    {
                        if (reader != null)
                            reader.Dispose();
                    }
                }
                finally
                {
                    if(response!=null)
                        ((IDisposable)response).Dispose();
                }
    

    As you can see, in CodeBlock1, you are trying to access stream which is trying to read from a Disposed (and dis-connected) HttWebResponse object.