2008-09-25 8 views
5

Al intentar llamar a Close o Dispose en un SqlDataReader obtengo una excepción expirada de tiempo de espera. Si usted tiene un DbConnection a SQL Server, puede reproducirse por sí mismo con:.NET: SqlDataReader.Close o .Dispose resultados en la excepción expirada de tiempo de espera

String CRLF = "\r\n"; 
String sql = 
    "SELECT * " + CRLF + 
    "FROM (" + CRLF + 
    " SELECT (a.Number * 256) + b.Number AS Number" + CRLF + 
    " FROM master..spt_values a," + CRLF + 
    "  master..spt_values b" + CRLF + 
    " WHERE a.Type = 'p'" + CRLF + 
    "  AND b.Type = 'p') Numbers1" + CRLF + 
    " FULL OUTER JOIN (" + CRLF + 
    "  SELECT (print("code sample");a.Number * 256) + b.Number AS Number" + CRLF + 
    "  FROM master..spt_values a," + CRLF + 
    "   master..spt_values b" + CRLF + 
    "  WHERE a.Type = 'p'" + CRLF + 
    "   AND b.Type = 'p') Numbers2" + CRLF + 
    " ON 1=1"; 

DbCommand cmd = connection.CreateCommand(); 
cmd.CommandText = sql; 
DbDataReader rdr = cmd.ExecuteReader(); 
rdr.Close(); 

Si llama reader.Close() o reader.Dispose() que va a lanzar una System.Data.SqlClient.SqlException:

  • ErrorCode: -2146232060 (0x80131904)
  • Mensaje: "tiempo de espera agotado el período de tiempo de espera transcurrido antes de la finalización de la operación o el servidor no está respondiendo.".

Respuesta

13

es porque acaba de abrir el lector de datos y no se ha reiterado por completo a través de él todavía. Necesitará .Cancelar() su objeto DbCommand antes de intentar cerrar un lector de datos que aún no se haya completado (y también la conexión Db). por supuesto, mediante .Cancelar() su DbCommand, no estoy seguro de esto pero puede encontrar alguna otra excepción. pero deberías atraparlo si sucede.

0

¿De dónde lees realmente los datos? Solo estás creando un lector, pero no leyendo Datos. Es sólo una suposición, pero tal vez el lector tiene problemas para cerrar si no está leyendo;)

DbDataReader rdr = cmd.ExecuteReader(); 
while(rdr.Read()) 
{ 
    int index = rdr.GetInt32(0); 
} 
+0

problema ocurre si se lee cero filas, una fila o muchas filas. –

2

Cruizer tenía la respuesta: llamar command.Cancel():

using (DbCommand cmd = connection.CreateCommand()) 
{ 
    cmd.CommandText = sql; 
    using (DbDataReader rdr = cmd.ExecuteReader()) 
    { 
     while (rdr.Read()) 
     { 
      if (WeShouldCancelTheOperation()) 
      { 
      cmd.Cancel(); 
      break; 
      } 
     } 
    }  
} 

También es útil a saber que se puede llamar cancelar incluso si el lector ya ha leído todas las filas (es decir, no arrojar algo "nada que cancelar" excepción.)

DbCommand cmd = connection.CreateCommand(); 
try 
{ 
    cmd.CommandText = sql; 
    DbDataReader rdr = cmd.ExecuteReader(); 
    try 
    { 
     while (rdr.Read()) 
     { 
      if (WeShouldCancelTheOperation()) 
      break; 
     } 
     cmd.Cancel(); 
    }  
    finally 
    { 
     rdr.Dispose(); 
    } 
} 
finally 
{ 
    cmd.Dispose(); 
} 
Cuestiones relacionadas