Bạn có thể bỏ qua bằng cách sử dụng xung quanh SqlCommand
. GC cuối cùng sẽ làm sạch nó cho bạn. Tuy nhiên, tôi khuyên bạn không nên làm điều này. Tôi sẽ giải thích tại sao.
SqlCommand
gián tiếp kế thừa từ System.ComponentModel.Component
và do đó kế thừa phương thức Finalizer
của nó. Không gọi xử lý trên SqlCommand
sẽ đảm bảo rằng lệnh được quảng bá ít nhất một thế hệ sau khi nó nằm ngoài phạm vi (trình thu gom rác .NET là generational gc). Ví dụ: khi lệnh nằm trong gen 1, nó sẽ chuyển sang gen 2. Các đối tượng finalizable được lưu giữ lâu hơn trong bộ nhớ để đảm bảo trình finalizer có thể chạy an toàn. Nhưng không chỉ bản thân lệnh được giữ trong bộ nhớ, mà tất cả các đối tượng mà nó tham chiếu đều đi kèm với nó đến thế hệ đó. Các đối tượng mà nó sẽ tham chiếu là SqlConnection
, danh sách các đối tượng SqlParameter
, chuỗi có thể lớn hơn CommandText
và nhiều đối tượng nội bộ khác mà nó tham chiếu.Bộ nhớ đó chỉ có thể được loại bỏ khi thế hệ đó được thu thập, nhưng thế hệ càng ít thì nó càng bị quét.
Do đó, không gọi điện sẽ cung cấp thêm áp lực bộ nhớ và công việc bổ sung cho chuỗi kết thúc.
Khi .NET không thể cấp phát bộ nhớ mới, CLR sẽ bắt buộc thu gom rác của tất cả các thế hệ. Sau đó, thời gian chạy thường sẽ có đủ không gian để cấp phát các đối tượng mới. Tuy nhiên, khi điều này bắt buộc thu thập xảy ra khi có rất nhiều đối tượng trong bộ nhớ vẫn phải được nâng cấp lên một gen tiếp theo (vì chúng có thể hoàn chỉnh, hoặc được tham chiếu bởi một đối tượng finalizable) có thể CLR không thể tự do đủ bộ nhớ. An OutOfMemoryException
sẽ là kết quả của việc này.
Tôi phải thừa nhận rằng tôi chưa bao giờ thấy điều này xảy ra, bởi vì các nhà phát triển không chỉ xử lý các đối tượng SqlCommand
của họ. Tuy nhiên, tôi đã thấy OOMs trong hệ thống sản xuất rất nhiều, gây ra bởi không xử lý các đối tượng đúng cách.
Tôi hy vọng điều này sẽ cung cấp một chút thông tin cơ bản về cách thức hoạt động của GC và rủi ro không được xử lý đúng (đối tượng cuối cùng) đúng cách. Tôi luôn bỏ tất cả các đồ vật dùng một lần. Trong khi một cái nhìn trong Reflector có thể chứng minh rằng điều này không nhất thiết đối với một kiểu nào đó, loại lập trình này dẫn đến mã ít bảo trì hơn và làm cho mã phụ thuộc vào hành vi bên trong của một kiểu (và hành vi này có thể thay đổi trong tương lai).
Bất kỳ lý do cụ thể nào khiến nó luôn rõ ràng? Câu trả lời này lệch khỏi mục đích thực sự của câu hỏi. – Nayan
@Nayan, hãy xem nhận xét của tôi cho câu trả lời của bạn. –
Caveat: đừng làm điều này cho các lớp Stream khi họ sở hữu các luồng đã truyền! Xem http://stackoverflow.com/questions/1065168/does-disposing-streamreader-close-the-stream – fmuecke