5

I am using windows forms.

My C# application contains 100 user controls. I show/hide one of those 100 user controls at a time when I need to and hide the rest. Each one of those user controls has 30 buttons and I subscribe to button event as following in the 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
}

So when I run the Application all the 100 User controls subscribe to the 30 buttons event and some of the user controls subscribe to the event but they are never used during the use of the application.

I read something about unsubscribing events here and Here but some answers say you should unsubscribe because it cause memory leak and some say you don't have to, therefore the answer is still not clear.

My question is do I have to unsubscribe from button events after using it for example: when I show/hide a user control. If yes, how can I subscribe from button event when a user control is shown and unsubscribe when it is not shown.

Kate
  • 935
  • 4
  • 14
  • 34

5 Answers5

10

Why unsubscribe?

It comes down to the lifespan of the subscriber (UserControl) compared to the subscribe (Button). The subscribe hold a reference to the subscriber. So if the subscribe have longer lifespan then the subscriber it will memory leak the subscriber.

So in your case you should ask if the Buttons will persist longer then the UserControl. If the Buttons have shorter on equal lifespan then no need to unsubscribe. Otherwise you will memory leak the UserControl.

In your case I guess that you don't need to unsubscribe.

R.Rusev
  • 1,111
  • 15
  • 19
  • Good explanation but what I still dont understand is: how can I know if the subscribe (button) have longer lifespan then the subscriber (userControl)? . I dont dispose user Control and all button still live there so who lives longer than who? – Kate Aug 23 '16 at 12:27
  • Well if the control contains the buttons, which is the case I quess then they have the same lifespan and you don't need to unsubscribe. – R.Rusev Aug 23 '16 at 12:28
1

If I got your question right - each control subscribing only on IT'S OWN children (30 buttons). The case when forgetting to unsubscribe is bad idea is when publisher (button) will live longer than subscriber (user control). Why? Because publisher will store link to subscriber and will prevent that subscriber to be disposed by Garbage Collector. In your case button will never live longer than it's parent - user control, so you don't need to unsubscribe.

1

You do not normally have to unsubscribe from events. That said, there are exceptional cases, when this is required.

This typically look like this: you have a long-lived object, that creates short-lived objects and attaches their methods to handle its (or some other long-lived object's) events. Alternatively, you create an object and attach its method to an event of different object with longer lifespan.

Now, when those short-lived objects go out of scope, they will still be attached to the event, so Garbage Collector will not reclaim them as long as the long-lived object (to whose event they are subscribed) is in scope. This is because it keeps their references to the objects that are supposed to handle its events.

In your case (and most other typical ones), the handlers are members of the class that owns the child control, so there is no risk of artificially prolonging any object's live. You do not need to explicitly unsubscribe here.

slawekwin
  • 6,270
  • 1
  • 44
  • 57
1

In your case there is no reason to worry. The two examples that you linked to have a different 'kind' of event, like this: if object A changes, then method X should be called, so X can act on or process the change in object A. For example A = inventory of a product; if the count of A goes to zero then it can no longer can be sold, or new items must be ordered, etc.

When responding to changed data, then the need to call X could cease to exist at some point in time, and then it may be beneficial to unregister the event, especially if there is no other way to break or disable the link.

However in a User Interface scenario such as yours, the need to call X usually stays present. If needed it can be controlled in another way, e.g. by disabling the button or by hiding it. There is really nothing expensive about having a link between a button and a method. The only reason to break the link would be 'I no longer want X to be called EVER if the button is clicked'.

Peter B
  • 22,460
  • 5
  • 32
  • 69
-1

You don't really have to unsubscribe, but you should. The way to unsubscribe would be:

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

//removing
button1.Click -= myHandler;
Manu Andrei
  • 62
  • 1
  • 15