开发者

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

This question already has answers here: Is it bad to not unregister event handlers? (2 answers) 开发者_运维技巧 Closed 9 years ago.

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?


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.


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.


If B holds a reference to A, A will not get Garbage Collected unless B is also eligible for Garbage Collection.

You shouldn't need a Dispose method for this. Once B has no references pointing to it either, the Garbage Collector will be smart enough to dispose both B and A.

If they are both alive for the life of the application, you don't need to deregister the event.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜