.NET:SqlDataReader.Close或.Dispose导致Timeout Expired异常

时间:2008-09-25 13:37:03

标签: .net sql-server database timeout

当尝试在SqlDataReader上调用Close或Dispose时,我得到一个超时过期的异常。如果您有SQL Server的DbConnection,则可以使用以下命令自行复制:

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

如果你调用reader.Close()或reader.Dispose(),它将抛出一个System.Data.SqlClient.SqlException:

  • ErrorCode:-2146232060(0x80131904)
  • 消息:“超时已过期。操作完成之前已超时,或服务器未响应。”

3 个答案:

答案 0 :(得分:13)

这是因为您刚刚打开数据阅读器并且尚未完全迭代它。在尝试关闭尚未完成的数据读取器(以及DbConnection)之前,您需要.Cancel()您的DbCommand对象。当然,通过.Cancel() - 你的DbCommand,我不确定这个,但你可能会遇到其他一些例外。但如果它发生,你应该抓住它。

答案 1 :(得分:2)

Cruizer得到了答案:call command.Cancel():

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

知道你可以调用取消也很有帮助,即使读者已经读过所有行(即它没有抛出一些“没有取消”异常。)

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

答案 2 :(得分:0)

你在哪里读到数据?你只是在创建一个阅读器,但不是在阅读数据。这只是一个猜测,但如果你不读书,读者可能会有问题;)

DbDataReader rdr = cmd.ExecuteReader();
while(rdr.Read())
{
    int index = rdr.GetInt32(0);
}
相关问题