여기에서 레거시 코드로 작업하고 있으며 SqlDataReader
닫히거나 처리되지 않는 인스턴스가 많이 있습니다. 연결이 끊어졌지만 리더를 수동으로 관리해야하는지 잘 모르겠습니다.
이로 인해 성능이 저하 될 수 있습니까?
답변
다음과 같은 독자를 사용하지 마십시오.
SqlConnection connection = new SqlConnection("connection string");
SqlCommand cmd = new SqlCommand("SELECT * FROM SomeTable", connection);
SqlDataReader reader = cmd.ExecuteReader();
connection.Open();
if (reader != null)
{
while (reader.Read())
{
//do something
}
}
reader.Close(); // <- too easy to forget
reader.Dispose(); // <- too easy to forget
connection.Close(); // <- too easy to forget
대신 using 문으로 래핑합니다.
using(SqlConnection connection = new SqlConnection("connection string"))
{
connection.Open();
using(SqlCommand cmd = new SqlCommand("SELECT * FROM SomeTable", connection))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader != null)
{
while (reader.Read())
{
//do something
}
}
} // reader closed and disposed up here
} // command disposed here
} //connection closed and disposed here
using 문을 사용하면 개체를 올바르게 처리하고 리소스를 확보 할 수 있습니다.
잊어 버린 경우 청소를 가비지 수집기에 맡기고 시간이 걸릴 수 있습니다.
답변
SqlCommand.ExecuteReader ()를 사용하여 인스턴스화 된 SqlDataReader를 삭제 해도 기본 연결이 닫히거나 삭제 되지 않습니다 .
두 가지 일반적인 패턴이 있습니다. 첫 번째로 리더는 연결 범위 내에서 열리고 닫힙니다.
using(SqlConnection connection = ...)
{
connection.Open();
...
using(SqlCommand command = ...)
{
using(SqlDataReader reader = command.ExecuteReader())
{
... do your stuff ...
} // reader is closed/disposed here
} // command is closed/disposed here
} // connection is closed/disposed here
데이터 액세스 방법으로 연결을 열고 판독기를 반환하는 것이 편리한 경우가 있습니다. 이 경우 반환 된 판독기가 CommandBehavior.CloseConnection을 사용하여 열리도록하는 것이 중요하므로 판독기를 닫거나 폐기하면 기본 연결이 닫힙니다. 패턴은 다음과 같습니다.
public SqlDataReader ExecuteReader(string commandText)
{
SqlConnection connection = new SqlConnection(...);
try
{
connection.Open();
using(SqlCommand command = new SqlCommand(commandText, connection))
{
return command.ExecuteReader(CommandBehavior.CloseConnection);
}
}
catch
{
// Close connection before rethrowing
connection.Close();
throw;
}
}
호출 코드는 다음과 같이 판독기를 처리해야합니다.
using(SqlDataReader reader = ExecuteReader(...))
{
... do your stuff ...
} // reader and connection are closed here.