Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get rid of event handlers safely?

Tags:

c#

events

Let's say I have a class A which can fire an event called X. Now I have a class B and in a method I get an instance to A and bind the event to a handler in B:

public void BindEvent(A a)
{
    a.X += AEventHandler;
}

I have three questions about this.

  • Is it true that when I now set the reference to the B instance to null, it won't be garbage collected since the garbage collector thinks it's still in use (thus keeping a useless and potentially interfering copy of B in memory).

  • What about when I have another object c (of class C) in which I have a reference to A called a ("this.a = new A()"). Then I call "b.BindEvent(this.a)", and in c I set the reference to a to null ("this.a = null"). Will this keep the copy of A in memory because it's referenced through the event in b?

  • If either or both are true of the above, how can I best circumvent these issues? If I have a whole list of event handlers (say 10 lines like "a.SomeEvent += SomeMethod") should I clean them all up again ("a.SomeEvent -= SomeMethod"). At which time or place in the code should I do these things?

Well it's gotten a bit fuzzy but I'm not sure how to explain in a better way. Please leave a comment if I need to explain something more detailed.

like image 218
pbean Avatar asked Jun 05 '09 11:06

pbean


2 Answers

so: A is the publisher and B is the subscriber?

first bullet: if B is the instance with AEventHandler - then it is still in use, so no, it won't get collected unless the a instance is unreachable.

second bullet: huh? (will read again...) If the A and B instances are both unreachable, they will be garbage collected; the event doesn't matter. If A is reachable, then B will stay alive. However, the event subscription never keeps A alive; it is one way... A can keep B alive, but B doesn't keep A alive. Does that cover it?

third bullet: in most cases, the two things have similar life expentency, so it isn't an issue. It only becomes an issue if the thing publishing the event lives a lot longer than the things with the handlers. In which case, you simply need to religiously clean up after yourself - for example: a.X -= AEventHandler. In particular, static events are evil for this reason.

like image 173
Marc Gravell Avatar answered Sep 20 '22 00:09

Marc Gravell


You should really unbind the event handler before destroying the class instance that it relates to. (Using your code as an exmaple.)

public void UnbindEvent(A a)
{
    a.X -= AEventHandler;
}

I would also ask, why are you setting class variables to null?

like image 28
ChrisBD Avatar answered Sep 22 '22 00:09

ChrisBD