Trước hết - trong ví dụ của bạn, bạn đang sử dụng giao diện IDisposable
, không liên quan gì đến GC. Về bản chất, mã của bạn biên dịch như sau:
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();
}
Kể từ cn.Dispose()
và cn.Close()
đều giống nhau trong trường hợp này - vâng, sau này là không cần thiết.
Bây giờ, nếu bạn muốn nói về GC, sau đó bạn muốn viết như thế này:
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.
Trong trường hợp này nó sẽ mất GC để đóng kết nối mở và gửi lại cho hồ bơi. Và trong trường hợp này, điều đó có nghĩa là bạn không thể dự đoán được khi nào điều đó xảy ra. Trong thực tế mã này sẽ (với xác suất cao) rò rỉ SqlConnections và sớm bạn sẽ chạy ra khỏi chúng (bạn sẽ nhận được một TimeoutException vì sẽ không có các kết nối có sẵn trong hồ bơi).
Vì vậy, vâng, ví dụ trên là cách chính xác. Bất cứ khi nào bạn sử dụng một số đối tượng thực hiện IDisposable
, hãy bọc nó trong khối using
. Và bạn không cần phải bận tâm với các .Close()
, mặc dù nó không làm tổn thương một trong hai. Cá nhân tôi không viết nó mặc dù. Ít mã hơn, ít lộn xộn hơn.
Nguồn
2010-08-23 09:20:17
vì bạn đang sử dụng câu lệnh 'using',' cn.Close() 'là hoàn toàn dư thừa. –
trong ví dụ của bạn, đó là IDispose/using() dọn dẹp kết nối, chứ không phải GC.Thực hành tốt (cần thiết) để kiểm soát tuổi thọ của các tài nguyên như kết nối và tệp. GC chỉ nên dựa vào tài nguyên bộ nhớ. – tenfour