title: StreamReader ReadLine throwing disposed exception rather than returning null
body: <p>I'm trying to fetch a text file from an FTP server, then read it line by line, adding each line to a list.</p>
  
  <p>My code seems to fit the standard pattern for this:</p>
  
  <pre><code>            var response = (FtpWebResponse)request.GetResponse();
              using (var responseStream = response.GetResponseStream())
              {
                  using (var reader = new StreamReader(responseStream))
                  {
                      string line;
                      while((line = reader.ReadLine()) != null)
                      {
                          lines.Add(line);
                      }
                  }
              }
  </code></pre>
  
  <p>But, for some reason, when reader.ReadLine() is called on the very last line of the file, it throws an exception, saying "Cannot access a disposed object".</p>
  
  <p>This is really weirding me out. If I remember correctly, the final line of a stream when there is no further data is <strong>null</strong>, right?</p>
  
  <p>In addition (while I'm not certain about this), this only seems to be happening locally; the live version of this service seems to be pootling along fine (albeit with some issues I'm trying to get to the bottom of). I certainly don't see this issue in my logs.</p>
  
  <p>Anyone have an ideas?</p>
  
  <p>EDIT: Here's the full text of the exception.</p>
  
  <pre><code>System.ObjectDisposedException: Cannot access a disposed object.
  Object name: 'System.Net.Sockets.NetworkStream'.
     at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
     at System.Net.FtpDataStream.Read(Byte[] buffer, Int32 offset, Int32 size)
     at System.IO.StreamReader.ReadBuffer()
     at System.IO.StreamReader.ReadLine()
     at CENSORED.CatalogueJobs.Common.FtpFileManager.ReadFile(String fileName, String directory) in C:\\Projects\\CENSORED_CatalogueJobs\\CENSORED.CatalogueJobs.Common\\FtpFileManager.cs:line 104
     at CENSORED.CatalogueJobs.CENSOREDDispatchService.CENSOREDDispatchesProcess.&lt;Process&gt;d__12.MoveNext() in C:\\Projects\\CENSORED_CatalogueJobs\\CENSORED.CatalogueJobs.CENSOREDDispatches\\CENSOREDDispatchesProcess.cs:line 95"
  </code></pre>
  
  <p>Type is "System.ObjectDisposedException". Sorry for censorship, exception contains my client's name.</p>
  
  <p>EDIT 2: Here's the code now, after being expanded out and removing a layer of usings (I think I've done it right).</p>
  
  <pre><code>            var response = (FtpWebResponse)request.GetResponse();
              using (var reader = new StreamReader(response.GetResponseStream()))
              {
                  string line = reader.ReadLine();
                  while(line != null)
                  {
                      lines.Add(line);
                      line = reader.ReadLine();
                  }
              }
  </code></pre>
  
  <p>EDIT 3: A slightly more wide view of the code (temporarily reverted for my sanity). This is essentially everything in the function.</p>
  
  <pre><code>            var request = (FtpWebRequest)WebRequest.Create(_settings.Host + directory + fileName);
  
              request.Method = WebRequestMethods.Ftp.DownloadFile;
              request.Credentials = new NetworkCredential(_settings.UserName, _settings.Password);
              request.UsePassive = false;
              request.UseBinary = true;
  
              var response = (FtpWebResponse)request.GetResponse();
              using (var responseStream = response.GetResponseStream())
              {
                  using (var reader = new StreamReader(responseStream))
                  {
                      string line;
                      while((line = reader.ReadLine()) != null)
                      {
                          lines.Add(line);
                      }
                  }
              }
  </code></pre>