Как закрыть DataReader на исключение
У меня есть следующий код в некоторых методах моего уровня данных:
StringBuilder sb = new StringBuilder();
SqlCommand s = new SqlCommand(sb.ToString(), conn);
try
{
SqlDataReader dr = s.ExecuteReader();
while(dr.Read())
DoSomething(dr);
}
catch (Exception ex)
{
sb.Append(Util.ExceptionRecursive(ex));
}
Дело в том, что доктор никогда не закрывается в случае исключения. И когда другой метод пытается получить доступ к другому считывателю данных, он выдает другое исключение, которое говорит что-то вроде: "Другой источник данных подключен к базе данных".
Я хочу закрыть мой DataReader в любом случае. Но это:
sb = new StringBuilder();
SqlCommand s = new SqlCommand(sb.ToString(), conn);
SqlDataReader dr;
try
{
dr = s.ExecuteReader();
while(dr.Read())
DoSomething(dr);
}
catch (Exception ex)
{
sb.Append(Util.ExceptionRecursive(ex));
}
finally
{
dr.Close();
}
Не будет работать, потому что в случае исключения dr может не иметь данных и не будет компилироваться.
Как мне тогда это сделать?
3 ответа
Вы должны использовать using
утверждение:
Генерирует finally
заблокировать, чтобы ваш ресурс всегда был расположен.
StringBuilder sb = new StringBuilder();
using (SqlCommand s = new SqlCommand(sb.ToString(), conn)) {
try
{
using (SqlDataReader dr = s.ExecuteReader()) {
while(dr.Read())
DoSomething(dr);
}
}
catch (Exception ex)
{
sb.Append(Util.ExceptionRecursive(ex));
}
}
Лучший способ, вероятно, это:
sb = new StringBuilder();
...
using (SqlCommand s = new SqlCommand(sb.ToString(), conn))
using (SqlDataReader dr = s.ExecuteReader())
{
try
{
while(dr.Read())
DoSomething(dr);
}
catch (Exception ex)
{
sb.Append(Util.ExceptionRecursive(ex));
}
}
Однако, если вы ожидаете (или нет) исключения во время выполнения SQL, вы должны разместить код обработки исключений снаружи:
sb = new StringBuilder();
...
try
{
using (SqlCommand s = new SqlCommand(sb.ToString(), conn))
using (SqlDataReader dr = s.ExecuteReader())
{
while(dr.Read())
DoSomething(dr);
}
}
catch (Exception ex)
{
sb.Append(Util.ExceptionRecursive(ex));
}