7

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がスローされます。

  • エラーコード:-2146232060(0x80131904)
  • メッセージ:「タイムアウトが期限切れになりました。操作が完了する前にタイムアウト期間が経過したか、サーバーが応答していません。」
4

3 に答える 3

16

これは、データリーダーを開いたばかりで、まだ完全に繰り返していないためです。まだ完了していないデータリーダー(およびDbConnectionも)を閉じる前に、DbCommandオブジェクトを.Cancel()する必要があります。もちろん、DbCommandを.Cancel()-ingすることで、これはわかりませんが、他の例外が発生する可能性があります。しかし、それが起こった場合は、それをキャッチする必要があります。

于 2008-09-25T13:40:45.377 に答える
3

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

また、リーダーがすでにすべての行を読み取った場合でも、Cancel を呼び出すことができることを知っておくと役立ちます (つまり、「キャンセルするものがない」という例外はスローされません)。

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();
}
于 2008-09-25T13:56:47.147 に答える
0

実際にどこでデータを読み取りますか? リーダーを作成しているだけで、データを読み取っていません。これは単なる推測ですが、読んでいない場合、リーダーを閉じるのに問題がある可能性があります;)

DbDataReader rdr = cmd.ExecuteReader();
while(rdr.Read())
{
    int index = rdr.GetInt32(0);
}
于 2008-09-25T13:45:31.793 に答える