2016-08-23 29 views
5

我正在使用Windows窗体。在c#中使用它之后,我是否必须取消订阅按钮事件?

我的C#应用​​程序包含100 user controls。当我需要并隐藏其余部分时,我显示/隐藏其中一个100 user controls。 那些user controls每个人都有30 buttons和我订阅button事件作为构造如下:

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 
    } 

所以,当我运行的应用程序的所有100 User controls订阅30 buttons事件和一些user controls订阅到事件,但在使用应用程序期间从不使用它们。

我读了一些关于取消订阅事件hereHere但有些答案说你应该取消订阅,因为它会导致内存泄漏,有人说你不必这样做,所以答案仍然不清楚。

我的问题是我必须退订button事件后使用它,例如:当我显示/隐藏user control。如果是,当user control显示时如何订阅button事件,如果未显示则取消订阅。

+0

是不是有一个显示/隐藏事件,你可以用来分别附加/分离事件处理程序? – PeteGO

+0

@PeteGO我现在看了一下,我没有找到,甚至没有找到,即使 – Kate

+0

有一个'IsVisibleChanged'事件,你可以使用。 – PeteGO

回答

8

为什么取消订阅?

与订阅(按钮)相比,它归结于订阅者(UserControl)的使用期限。该订阅持有对用户的引用。所以如果订阅有更长的使用期限,那么订阅者会记忆用户泄漏。

所以在你的情况下,你应该问是否按钮将持续更长的UserControl。如果按钮的寿命相同,则不需要退订。否则,你会内存泄漏UserControl。

在你的情况下,我想你不需要退订。

+0

很好的解释,但我仍然不明白的是:我怎么知道订阅(按钮)是否有更长的使用寿命,然后订阅者(userControl)? 。我不处理用户控制和所有的按钮仍然住在那里谁比谁长寿? – Kate

+0

那么如果控件包含按钮,这是我的情况,那么它们具有相同的使用寿命,并且不需要取消订阅。 –

-1

你并不真的必须取消订阅,但你应该。退订方式是:

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

//removing 
button1.Click -= myHandler; 
1

如果我收到了你的问题的权利 - 每个控制只在它自己的孩子(30个键)订阅。忘记取消订阅的情况不好是当发布者(按钮)将比订阅者(用户控件)寿命更长时。为什么?因为发布者将存储链接到订阅者并且将阻止该订阅者被垃圾收集器处置。 在你的病例按钮永远不会比它的父 - 用户控制寿命长,所以你不需要退订。

1

您不需要通常必须退订事件。也就是说,有些例外情况需要时。

这通常看起来像这样:你有一个长寿命的对象,它创建短暂的对象并附加它们的方法来处理它的(或其他长寿命对象的)事件。或者,您可以创建一个对象并将其方法附加到具有更长使用寿命的不同对象的事件。

现在,当这些短期对象超出范围时,它们仍将附加到事件上,因此Garbage Collector只要长寿命对象(对其订阅的事件而言)都不会收回它们范围。这是因为它保留了对应该处理其事件的对象的引用。

对于您的情况(以及大多数其他典型情况),处理程序是拥有子控件的类的成员,因此不存在人为延长任何对象生命的风险。您无需在此明确退订。

1

在你的情况下,没有理由担心。您链接的两个示例具有不同的“种类”事件,如下所示:如果对象A发生更改,则应调用方法X,以便X可以处理或处理对象A中的更改。 例如A =库存产品的;如果A的计数为零,则不能再销售,或者必须订购新的物品等。

当响应改变的数据时,则需要调用X可能会在某个点停止存在时间,然后注销该事件可能是有益的,特别是如果没有其他方式打破或禁用该链接。

但是,在您的用户界面场景中,需要调用X通常仍然存在。如果需要,可以用另一种方式进行控制,例如,通过禁用按钮或隐藏它。在按钮和方法之间建立链接确实没有任何代价。断开链接的唯一理由是'如果点击按钮,我不希望X被称为EVER'。

相关问题