Interesting event “Dispose” behaviour

大兔子大兔子 提交于 2019-12-04 12:25:42

The event, which is still in scope since it is on the main form, still has a reference to the delegate in the child window. Therefore closing the window will not dispose of the object because it too is still in scope through this reference. This is a very common way the get a "memory leak" in .NET. Also consider that because the child window is still in scope everything inside the window is still in scope and also won't get collected.

As for why the window doesn't detach all event handlers on close. It would be very strange behaviour if it did. Just because you have closed a window doesn't mean you are finished with it, you could reopen it, save data from it to persist state. Calling close on a window has no special properties over calling any other method, it doesn't dispose of the window, mark it for collection or anything else.

You are correct. When you register an event, a reference to your form is added to the event delegate (in the object that owns that event). Unless you remove the registration, your form will never get garbage collected because it there is still at least one reference to it (the delegate), and the calls with still be issued when the event is raised.

You should always ensure events get unsubscribed, to avoid this kind of leakage.

Yes, this is the behaviour by design, which is also the reason why the WeakEvent pattern was concieved.

Your event subscription "counts" as a reference to your child form. (so your child forms are not being garbage collected either).

To see what's going on, look up the help on a delegate. it has a member called Target (of type object) that points to the subscriber. So, you still have a reference chain alive:

MDI Parent (event publisher) --> the delegate --> your child form.

You have to clean up your event subscriptions in Dispose() or your child forms will never be eligible for garbage collection.

Now, if you look around on the web for "weak ref events", you will find a number of workarounds that people have posted for defining weak events. Here's just one example: http://www.codeproject.com/KB/cs/weakeventhandlerfactory.aspx

I have had to prototype one as well, and I would be happy to share it if you want it. However, my advice would be to stick with regular events and clean up in Dispose().

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!