2009-12-28 30 views
8

Có nhiều chủ đề (a, b, c vv) về thực tế là Rõ ràng() mặt hàng ing trong container thành phần .NET không Vứt bỏ họ (bằng cách gọi Dispose (đúng).Điều khiển rõ ràng không thải bỏ chúng - rủi ro là gì?

thường xuyên nhất, IMHO, các thành phần Clear-ed không được sử dụng nữa trong việc áp dụng, vì vậy nó cần một cách rõ ràng được xử lý sau khi Xoá chúng từ container mẹ.

lẽ là một ý tưởng tốt mà phương pháp thu thập của Clear đã có một bool tham số dispose rằng khi trong sự thật cũng phân phối các yếu tố thu thập trước khi loại bỏ khỏi danh sách?

+0

Nếu có một cuộc gọi để Vứt bỏ trong finalizer, họ sẽ nhận được xử lý. Nếu không có, thì có lẽ (nếu lập trình viên tuân theo các thực hành được chấp nhận) không có gì không được quản lý để vứt bỏ và nó an toàn để chỉ thu gom rác. –

+0

@Aviad: Vấn đề mà phương pháp Vứt bỏ sẽ không bao giờ được gọi bởi GC, vì vậy bạn cần tự làm điều đó trước khi gọi Clear trên bộ sưu tập. – serhio

+0

Ý của tôi là, nếu người lập trình của điều khiển không đặt cuộc gọi Dispose vào finalizer của nó (được gọi khi đối tượng được thu thập rác) - thì có lẽ không có gì để vứt bỏ. –

Trả lời

15

Yêu cầu sửa đổi như thế này là vô nghĩa, nhóm Windows Forms đã bị giải tán khá lâu trước đây. Nó đang ở chế độ bảo trì, chỉ xem xét các vấn đề bảo mật và tính không tương thích của hệ điều hành.

Đó là trường hợp đơn giản, đủ để tạo ra phương pháp riêng của mình để làm điều này:

public static class ExtensionMethods { 
    public static void Clear(this Control.ControlCollection controls, bool dispose) { 
     for (int ix = controls.Count - 1; ix >= 0; --ix) { 
     if (dispose) controls[ix].Dispose(); 
     else controls.RemoveAt(ix); 
     } 
    } 
    } 

Bây giờ bạn có thể viết:

panel1.Controls.Clear(true); 
+1

IIRC, khi bạn 'Vứt bỏ' một 'Điều khiển', nó sẽ tự động loại bỏ điều khiển khỏi' ControlCollection' tương ứng, vì vậy bạn thực sự không cần 'RemoveAt' (và có thể kết thúc bằng' IndexOutOfRangeException'). – Aaronaught

+0

vâng ... ít nhất cho .NET 2 điều này sẽ không hoạt động. Nhưng câu hỏi là một chút khác. Có một "nguy cơ" làm gọi "Clear" mà không vứt bỏ? – serhio

+2

Tất nhiên, bạn sẽ bị rò rỉ các điều khiển. Không phải là rõ ràng từ các chủ đề khác? –

0

trả lời "là những gì mà nguy cơ" câu hỏi, nguy cơ (hoặc một rủi ro) đang chạy ra khỏi tay cầm cửa sổ, mặc dù nó có thể mất một lúc.

Tôi có "trình thiết kế cửa sổ" tạo cửa sổ từ tập lệnh. Mỗi khi tôi thay đổi kịch bản, cửa sổ được xây dựng lại (các điều khiển được xóa và readded). Với một cửa sổ đặc biệt phức tạp và sử dụng Controls.Clear() mỗi lần, sau hàng chục lần làm mới, cuối cùng tôi sẽ nhận được ngoại lệ "không có cửa sổ xử lý" và không thể tạo thêm bất kỳ điều khiển nào nữa.

đủ dễ dàng để thay thế Controls.Clear() cuộc gọi với một cái gì đó như:

Controls.Cast<Control>().ForEach(c => c.Dispose()); 
Các vấn đề liên quan