title: How to address SqlConnection being closed from inside ExecuteReader?
body: <p>I have an open <code>SqlConnection</code> and code like this:</p>
  
  <pre><code>using (var transaction = connection.BeginTransaction()) {
     using (var command = connection.CreateCommand()) {
         command.Transaction = transaction;
     command.CommandText = "MyQueryText";
         using( var reader = command.ExecuteReader() ) {
             //read data
         }
     }
  }
  </code></pre>
  
  <p><a href="https://stackoverflow.com/q/13968342/57428">I've been experiencing some "impossible code" symptoms</a> and subscribed to <code>SqlConnection.StateChange</code> event and now I've found that at some point the event is invoked with the following stack (state is being changed from <code>Open</code> to <code>Closed</code>):</p>
  
  <pre><code>at MyHandler.onStateChange(Object sender, StateChangeEventArgs e)
  at System.Data.ProviderBase.DbConnectionInternal.CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory)
  at System.Data.SqlClient.SqlConnection.Close()
  at System.Data.SqlClient.SqlInternalConnectionTds.BreakConnection()
  at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
  at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj)
  at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()
  at System.Data.SqlClient.TdsParserStateObject.ReadByte()
  at System.Data.SqlClient.SqlDataReader.SetMetaData(_SqlMetaDataSet metaData, Boolean moreInfo)
  at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
  at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
  at System.Data.SqlClient.SqlDataReader.get_MetaData()
  at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
  at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
  at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
  at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
  at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
  at System.Data.SqlClient.SqlCommand.ExecuteReader()
  // my code calling `ExecuteReader()`
  </code></pre>
  
  <p>so the runtime encounters some random error (network connectivity problem I guess) and closes the connection and then returns a closed reader object to my code and my attempts to use the returned reader yield <code>InvalidOperationException</code>.</p>
  
  <p>I need to work it around somehow. Obviously random network errors will happen. I have retry logic in my code that can deal with <code>SqlException</code>s thrown on network issues but here I face a closed reader and then an <code>InvalidOperationException</code>.</p>
  
  <p>My first idea is to write my own <code>ExecuteReader()</code> that would call native <code>ExecuteReader()</code>, check whether a closed reader is returned and if that happens throw a new <code>ClosedReaderReturnedException</code> and I'll also change the retry code so that it reacts to such exceptions too and reruns the query.</p>
  
  <p>Is my solution good? Is there a better solution?</p>