Я обычно пишу мой DataReader
кодируйте как это:
try
{
dr = cmd.ExecuteReader(CommandBehavior.SingleResult);
while (dr.Read())
{
// Do stuff
}
}
finally
{
if (dr != null) { dr.Close(); }
}
Действительно ли безопасно заменить try
и finally
только с a using
блок вокруг DataReader
создание? Причина интересно, то, потому что во всех примерах Microsoft я видел, что они используют использование для соединения, но всегда явно звонят Close()
на DataReader
.
Heres пример от Получения Данных Используя DataReader (ADO.NET):
static void HasRows(SqlConnection connection)
{
using (connection)
{
SqlCommand command = new SqlCommand(
"SELECT CategoryID, CategoryName FROM Categories;",
connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine("{0}\t{1}", reader.GetInt32(0),
reader.GetString(1));
}
}
else
{
Console.WriteLine("No rows found.");
}
reader.Close();
}
}
Да. Использование
вызовов разрешит. Вызов утилизации на SQLDatareader закрывает его.
Это PSuedo-код Sqldatareader Glianted из отражателя :
public void Dispose()
{
this.Close();
}
public override void Close()
{
if( !IsClosed )
CloseInternal(true);
}
private void CloseInternal(bool closeReader)
{
try
{
// Do some stuff to close the reader itself
}
catch(Exception ex)
{
this.Connection.Abort();
throw;
}
if( this.Connection != null && CommandBehavior.CloseConnection == true )
{
this.Connection.Close();
}
}
Из того, что я могу вспомнить, если в блоке Use происходит исключение, то на объект все равно вызывается метод Dispose. Обычно у меня есть оператор Use для всех одноразовых объектов, без метода Try...Catch.
EDIT: Забыл сказать, что для некоторых объектов вызов Dispose в свою очередь вызовет Close для этого объекта.
Обычно , используя()
, вызывает Dispose()
и этот вызов close()
по очереди.
В случае DataReader вызов Close осуществляется только при установке CommandBehavior.CloseConnection
(см. комментарии к данной статье http://weblogs.asp.net/joseguay/archive/2008/07/22/ensure-proper-closure-amp-disposal-of-a-datareader.aspx).
EDIT: В этой статье говорится о чем-то интересном:
Метод Close() на SqlDataReader вызывает функцию InternalClose(). метод, который не вызывает Dispose. Обратите внимание, что ранее мы указывали правильным способом сделать это было иметь твоя близко расположенная распорядительница. Чтобы сделать это ещё больше сбивает с толку функцию Dispose() на самом деле метод вызывает Close() метод, поэтому для данного объекта заказ наоборот.