Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to Dispose to deregister events? [duplicate]

Say I have two classes, and neither of them are GUI components. Class A is a short lived object that registers for an event declared by a long lived object B. For example

public A(B b)
{
   b.ChangeEvent += OnChangeEvent;
}

If A never deregisters from B's event, will A never be garbage collected? Does A need a Dispose method just to deregister from B's event?

There is also a related second question. If A and B should both live for the entire execution time of the application, does A need to deregister?

like image 449
Sean Avatar asked Apr 13 '10 14:04

Sean


2 Answers

To your first question: Yes. B has a reference to A. That way A will live as long as B. This is a nice way to loose memory in a UI app if you e.g. register with an event like App.OnIdle.

To the second: At the end everything will be killed.

like image 157
flq Avatar answered Sep 25 '22 15:09

flq


The proper place to disconnect the event would, as you suspect, be in the IDisposable.Dispose method of A. There isn't really any good alternative. It would be useless to try to disconnect the event within A's finalizer/destructor, since the only way A would ever be eligible for garbage collection prior to its disconnecting from B would be for B to become itself eligible for garbage collection; once that has happened, the subscription would become a moot point so it wouldn't matter whether it was cleaned up or not.

If it's necessary for events from abandoned short-lived subscribers to be cleaned up within the lifetime of a long-lived publisher, there are ways of doing that if the publishing and subscribing classes cooperate. For example, the event subscriber's public face can be a wrapper object which holds a reference to the actual event subscriber, with the subscriber itself not holding a strong reference to that public object. Under that scenario, the event subscription would not prevent the public object from falling out of scope and becoming eligible for finalization. A finalizer in the public object could notify the subscribing object that the subscription would no longer be needed and it should unsubscribe. Since such notification would arrive asynchronously, the object publishing the subscription would have to offer a means by which subscribers could be asynchronously unsubscribed. This could be done by a normal "unsubscribe" request, provided that the publishing event guaranteed it to be non-blocking and thread-safe; unfortunately, most events offer no such guarantee.

like image 22
supercat Avatar answered Sep 24 '22 15:09

supercat