Прежде всего - в вашем примере вы используете интерфейс IDisposable
, который вообще не имеет ничего общего с GC.По сути, ваш код компилируется следующим образом:
SqlConnection cn = null;
try
{
cn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString());
cn.Open();
// Set all previous settings to inactive
using (SqlCommand cmd = new SqlCommand("UPDATE tblSiteSettings SET isActive = 0", cn))
{
cmd.ExecuteNonQuery();
}
cn.Close();
}
finally
{
if ( cn != null )
cn.Dispose();
}
Поскольку cn.Dispose()
и cn.Close()
в этом случае одинаковы - да, последний является избыточным.
Теперь, если выЕсли вы хотите поговорить о GC, то напишите так:
SqlCOnnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString());
cn.Open();
// Set all previous settings to inactive
using (SqlCommand cmd = new SqlCommand("UPDATE tblSiteSettings SET isActive = 0", cn))
{
cmd.ExecuteNonQuery();
}
cn = null; // Or just leave scope without doing anything else with cn.
В этом случае потребуется GC, чтобы закрыть открытое соединение и вернуть его в пул.И в этом случае это будет означать, что вы не можете предсказать, когда это произошло.На практике этот код (с высокой вероятностью) будет пропускать SqlConnections, и вскоре вы их исчерпаете (вы получите TimeoutException, поскольку в пуле не будет доступных подключений).
Так что да,Ваш приведенный выше пример - правильный путь.Всякий раз, когда вы используете какой-либо объект, который реализует IDisposable
, оберните его в блок using
.И вам не нужно беспокоиться о .Close()
, хотя это тоже не повредит.Я лично не пишу это все же.Меньше кода, меньше беспорядка.