Frage

Beim Versuch Schließen anrufen oder Entsorgen auf einer SqlDataReader i ein Timeout abgelaufen Exception. Wenn Sie eine DbConnection zu SQL Server haben, können Sie es reproduzieren, sich mit:

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();

Wenn Sie rufen reader.Close () oder reader.Dispose () wird es eine System.Data.SqlClient.SqlException werfen:

  • Error-Code: -2146232060 (0x80131904)
  • Nachricht: „Timeout abgelaufen Die Timeout-Zeit vor dem Abschluss der Operation vergangen oder der Server reagiert nicht.“.
War es hilfreich?

Lösung

es ist, weil Sie nur den Datenleser geöffnet haben und nicht vollständig durch sie noch wiederholt. Sie werden Ihr DbCommand Objekt .Cancel () benötigen, bevor Sie einen Datenleser zu schließen versuchen, die noch nicht abgeschlossen ist (und die DbConnection als auch). natürlich durch .Cancel () - ing Ihre DbCommand, ich bin nicht sicher, ob dies aber Sie könnten eine andere Ausnahme begegnen. aber Sie sollten es nur fangen, wenn es passiert.

Andere Tipps

Cruizer hatte die Antwort: call command.Cancel ():

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

Es ist auch hilfreich zu wissen, dass Sie sogar Abbrechen anrufen können, wenn der Leser bereits alle Zeilen gelesen hat (dh es ist nicht etwas „nichts abbrechen“ Ausnahme wirft.)

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();
}

Wo lesen Sie die Daten tatsächlich? Sie erstellen nur einen Leser, aber nicht Daten zu lesen. Das ist nur eine Vermutung, aber vielleicht der Leser hat Probleme zu schließen, wenn Sie nicht lesen;)

DbDataReader rdr = cmd.ExecuteReader();
while(rdr.Read())
{
    int index = rdr.GetInt32(0);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top