2010-06-30 41 views
10

Tôi đang làm một số phát triển ASP.NET trong VS và vừa tìm thấy một gợi ý nhỏ thú vị mã (Tôi nghĩ rằng họ đến từ coderush nhưng tôi có thể sai).Tại sao tôi cần phải gọi dispose trên ASP.NET Controls?

Bất cứ khi nào tôi tạo điều khiển, nó cho tôi biết rằng tôi nên sử dụng câu lệnh "sử dụng" cho họ. Tôi là một chút bối rối như những gì đang xảy ra ở đây mặc dù. với việc sử dụng mã của tôi trông giống như sau:

using (HtmlTableRow tableRow = new HtmlTableRow()) 
{ 
    tableRow.Attributes.Add("class", isOddRow ? "OddRow" : "EvenRow"); 
    listingTable.Rows.Add(tableRow); 
    addCell(tableRow, row, "issueId"); 
    addCell(tableRow, row, "Title"); 
    addCell(tableRow, row, "Type"); 
    addCell(tableRow, row, "Summary"); 
} 

Vì vậy, tôi hy vọng rằng ở cuối tuyên bố sử dụng, nó sẽ gọi xử lý trên bảngRow. Tuy nhiên, tài liệu trong thư viện MSDN cho biết:

Phương pháp vứt bỏ để kiểm soát ở trạng thái không sử dụng được. Sau khi gọi phương thức này, bạn phải giải phóng tất cả các tham chiếu vào điều khiển để bộ nhớ mà nó đang chiếm có thể là được thu hồi bởi bộ sưu tập rác.

Vì vậy, tôi hy vọng rằng bây giờ tôi có một đối tượng không sử dụng được trong cấu trúc điều khiển của mình để nó có thể bị hỏng hoặc không hiển thị hay gì đó. Tuy nhiên, mọi thứ dường như chỉ hoạt động tốt.

Vì vậy, điều tôi tự hỏi là tại sao tất cả các điều khiển đều dùng một lần? Có phải chỉ vì một số người trong số họ sẽ và làm cho họ tất cả các phương tiện dùng một lần mà một cuộc gọi để vứt bỏ ở cấp cao nhất sau đó có thể được chuyển xuống cho tất cả các điều khiển con đệ quy?

Tôi nghĩ rằng tôi sẽ hiểu nếu không thực tế là các tài liệu nói rõ ràng rằng việc vứt bỏ một điều khiển làm cho nó không sử dụng được ... Các tài liệu có đúng không?

+0

Làm cách nào chúng tôi có thể xử lý các đối tượng mồ côi (@Toby đã đề cập) nếu chúng tôi không sử dụng khối "đang sử dụng"? – Lijo

Trả lời

14

Bạn không nên thực sự làm điều này. Những gì bạn cần làm là đảm bảo rằng listingTable nằm trong bộ sưu tập Controls để nó sẽ được xử lý khi Trang được xử lý. Đối tượng listingTable sau đó chịu trách nhiệm xử lý đúng tất cả các con của nó.

Đó là lý do tại sao tất cả các đối tượng Control triển khai giao diện IDisposable. Bằng cách đó, mỗi kiểm soát của phụ huynh có thể gọi Dispose trên tất cả các trẻ em của nó mà không cần phải thử nghiệm từng lần một. Mỗi điều khiển là trách nhiệm cá nhân để xác định xem nó có thực sự có bất kỳ thứ gì cần được dọn dẹp khi phương thức Dispose của nó được gọi hay không.

Tài liệu không sai. Bất kỳ đối tượng được viết đúng cách nào thực hiện IDisposable và có dữ liệu trạng thái thực sự được dọn sạch trong quá trình xử lý sẽ ném một ObjectDisposedException nếu bất kỳ thuộc tính hoặc phương thức công cộng/được bảo vệ/nội bộ nào được truy cập sau khi nó đã được xử lý. (Giả sử trạng thái không hợp lệ sau khi Dispose đã được gọi.) Một số loại sẽ bỏ qua quy tắc này nếu chúng không thực sự có bất kỳ thứ gì để dọn sạch và không phải lo lắng về trạng thái không hợp lệ.

Lý do bạn đang nhận được một gợi ý để quấn nó trong một khối using được vì máy phân tích không nhận ra rằng listingTable sẽ vứt bỏ Rows bộ sưu tập của mình, mà sẽ xử lý từng đối tượng hàng đó đã được thêm vào nó. Ngoài ra, nếu một ngoại lệ được ném giữa HtmlTableRow tableRow = new HtmlTableRow()listingTable.Rows.Add(tableRow), đối tượng HtmlTableRow sẽ là 'mồ côi' và không nằm trong phân cấp IDisposable của đối tượng khác. Phân tích mã muốn bạn sử dụng khối thử/cuối cùng để xử lý ngay lập tức HtmlTableRow nếu điều này xảy ra.

+1

Cảm ơn. Tôi đã có một sự nghi ngờ về hầu hết những điều đó nhưng nó tốt để có được một chút chi tiết hơn về những gì đang xảy ra ở đây. Tôi thậm chí còn không coi là "mồ côi" của sự kiểm soát. – Chris

+0

Làm cách nào chúng ta có thể xử lý các đối tượng 'mồ côi' nếu chúng ta không sử dụng khối" đang sử dụng "? – Lijo

+0

@Lijo: Sử dụng khối thử/cuối cùng – Toby

Các vấn đề liên quan