2016-08-23 15 views
5

Tôi đang sử dụng biểu mẫu cửa sổ.Tôi có phải hủy đăng ký khỏi các sự kiện của nút sau khi sử dụng nó trong C# không?

Ứng dụng C# của tôi chứa 100 user controls. Tôi hiển thị/ẩn một trong số 100 user controls tại một thời điểm khi tôi cần và ẩn phần còn lại. Mỗi một trong những user controls có 30 buttons và tôi đăng ký vào button sự kiện như sau trong constructor:

public UserControl1() 
    { 
     InitializeComponent(); 


      button1.Click += new EventHandler(MyButtonClick); 
      button2.Click += new EventHandler(MyButtonClick); 
      . 

      . 
      button30.Click += new EventHandler(MyButtonClick); 



    } 

    void MyButtonClick(object sender, EventArgs e) 
    { 
     // do something 
    } 

Vì vậy, khi tôi chạy ứng dụng tất cả 100 User controls đăng ký vào các sự kiện 30 buttons và một số các user controls đăng ký cho sự kiện này nhưng chúng không bao giờ được sử dụng trong quá trình sử dụng ứng dụng.

Tôi đọc nội dung nào đó về hủy đăng ký sự kiện hereHere nhưng một số câu trả lời cho biết bạn nên hủy đăng ký vì nó gây rò rỉ bộ nhớ và một số nói rằng bạn không phải làm vậy, do đó câu trả lời vẫn không rõ ràng.

Câu hỏi của tôi là tôi phải hủy đăng ký từ button sự kiện sau khi sử dụng ví dụ: khi tôi hiển thị/ẩn user control. Nếu có, làm thế nào tôi có thể đăng ký từ sự kiện button khi một user control được hiển thị và hủy đăng ký khi nó không được hiển thị.

+0

Không có sự kiện hiển thị/ẩn mà bạn có thể sử dụng để đính kèm/tách trình xử lý sự kiện tương ứng không? – PeteGO

+0

@PeteGO Tôi đã có một cái nhìn bây giờ và tôi đã không tìm thấy hiển thị ngay cả – Kate

+0

Có một sự kiện 'IsVisibleChanged' mà bạn có thể sử dụng. – PeteGO

Trả lời

8

Tại sao nên hủy đăng ký?

Nó đi kèm với tuổi thọ của người đăng ký (UserControl) so với đăng ký (Nút). Đăng ký giữ một tham chiếu đến người đăng ký. Vì vậy, nếu các thuê bao có tuổi thọ lâu hơn sau đó các thuê bao nó sẽ bộ nhớ bị rò rỉ các thuê bao.

Vì vậy, trong trường hợp của bạn, bạn nên hỏi xem các nút sẽ tồn tại lâu hơn sau đó là UserControl. Nếu các nút có thời lượng ngắn hơn trên tuổi thọ bằng nhau thì không cần phải hủy đăng ký. Nếu không, bạn sẽ bị rò rỉ bộ nhớ UserControl.

Trong trường hợp của bạn, tôi đoán rằng bạn không cần phải hủy đăng ký.

+0

Giải thích tốt nhưng những gì tôi vẫn không hiểu là: làm thế nào tôi có thể biết nếu đăng ký (nút) có tuổi thọ dài hơn sau đó các thuê bao (userControl)? . Tôi không vứt bỏ điều khiển người dùng và tất cả các nút vẫn còn sống ở đó để những người sống lâu hơn ai? – Kate

+0

Vâng, nếu điều khiển chứa các nút, đó là trường hợp tôi quess sau đó họ có cùng tuổi thọ và bạn không cần phải bỏ đăng ký. –

-1

Bạn không thực sự phải hủy đăng ký, nhưng bạn nên làm như vậy. Cách hủy đăng ký sẽ là:

//adding 
EventHandler myHandler = new EventHandler(MyButtonClick); 
button1.Click += myHandler; 

//removing 
button1.Click -= myHandler; 
1

Nếu tôi có câu hỏi đúng - mỗi kiểm soát chỉ đăng ký trên trẻ em của IT (30 nút). Các trường hợp khi quên để bỏ đăng ký là ý tưởng tồi là khi nhà xuất bản (nút) sẽ sống lâu hơn so với thuê bao (kiểm soát người dùng). Tại sao? Bởi vì nhà xuất bản sẽ lưu trữ liên kết đến người đăng ký và sẽ ngăn chặn người đăng ký đó xử lý bởi Garbage Collector. Trong trường hợp của bạn nút sẽ không bao giờ sống lâu hơn là cha mẹ - người dùng kiểm soát, do đó bạn không cần phải bỏ đăng ký.

1

Bạn không thông thường phải hủy đăng ký khỏi các sự kiện. Điều đó nói rằng, có những trường hợp đặc biệt, khi điều này là bắt buộc. Điều này thường trông như thế này: bạn có một đối tượng tồn tại lâu dài, tạo ra các đối tượng tồn tại trong thời gian ngắn và gắn các phương thức của chúng để xử lý các sự kiện của nó (hoặc một số đối tượng tồn tại lâu dài khác) của nó. Ngoài ra, bạn tạo một đối tượng và đính kèm phương thức của nó vào một sự kiện của đối tượng khác nhau với tuổi thọ dài hơn.

Bây giờ, khi các đối tượng sống ngắn đó nằm ngoài phạm vi, chúng sẽ vẫn được đính kèm với sự kiện, vì vậy Garbage Collector sẽ không lấy lại chúng miễn là đối tượng tồn tại lâu dài (có sự kiện được đăng ký) phạm vi. Điều này là bởi vì nó giữ tài liệu tham khảo của họ để các đối tượng được cho là để xử lý các sự kiện của nó.

Trong trường hợp của bạn (và hầu hết các trường hợp điển hình khác), trình xử lý là thành viên của lớp sở hữu quyền kiểm soát trẻ em, vì vậy không có rủi ro kéo dài bất kỳ đối tượng sống nào của đối tượng. Bạn không cần phải hủy đăng ký một cách rõ ràng tại đây.

1

Trong trường hợp của bạn, không có lý do gì phải lo lắng. Hai ví dụ mà bạn liên kết có một loại 'sự kiện' khác nhau, như thế này: nếu đối tượng A thay đổi, thì phương thức X nên được gọi, vì vậy X có thể hoạt động hoặc xử lý thay đổi trong đối tượng A. Ví dụ: A = khoảng không quảng cáo của một sản phẩm; nếu số lượng A đến 0 thì không còn có thể bán được nữa, hoặc các mặt hàng mới phải được đặt hàng, v.v.

Khi trả lời dữ liệu thay đổi, thì cần gọi X có thể chấm dứt tồn tại tại một số thời điểm thời gian, và sau đó nó có thể có lợi để unregister sự kiện, đặc biệt là nếu không có cách nào khác để phá vỡ hoặc vô hiệu hóa các liên kết.

Tuy nhiên, trong trường hợp Giao diện người dùng như của bạn, sự cần thiết phải gọi X thường tồn tại. Nếu cần thiết, nó có thể được kiểm soát theo cách khác, ví dụ: bằng cách tắt nút hoặc ẩn nó. Thực sự không có gì đắt về việc có một liên kết giữa một nút và một phương thức. Lý do duy nhất để ngắt liên kết sẽ là 'Tôi không còn muốn X được gọi là EVER nếu nút được nhấp'.

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