2008-09-25 2 views
5

при попытке вызова Close или Dispose на SqlDataReader я получить таймаут исключение. Если у вас есть DBConnection к SQL Server, вы можете воспроизвести его самостоятельно с:.NET: SqlDataReader.Close или .Dispose приводит таймаут исключения

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)
  • сообщение: «время ожидания истекло время ожидания истекло до завершения операции или сервер не отвечает.».

ответ

13

Это потому, что вы только что открыли устройство для чтения данных и еще не полностью повторили его. вам нужно будет .Cancel() ваш объект DbCommand, прежде чем пытаться закрыть устройство чтения данных, которое еще не завершено (и DbConnection также). конечно, с помощью .Cancel() - вашего DbCommand, я не уверен в этом, но вы можете столкнуться с каким-то другим исключением. но вы должны просто поймать его, если это произойдет.

0

Где вы на самом деле читать данные? Вы просто создаете читателя, но не читаете «Данные». Это только предположение, но, может быть, у читателя есть проблемы, чтобы закрыть, если вы не читаете;)

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

Проблема происходит, если вы читаете ноль строк, строк или нескольких строк. – 2008-09-25 13:47:24

2

Cruizer был ответ: позвонить 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(); 
} 
Смежные вопросы