![]() | |
![]() |
| | Thread Tools | Search this Thread | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
Hi, I have a weird situation and I was wondering if anyone can help out. In my WinForms application, I have several UserControls which contain other UserControls. Some of the "inner" UserControls raise events, which are handled by the "parent" UserControls. The event handling is performed using an anonymous event handler. Using sos.dll, I discovered that the UserControls (parent and child) are not elligable for GC, when I'm disposing of the "parent" UserControl. I'm also making sure that the child's Dispose() is called, so please read on. However, if I change the anonymous event handler to a "normal" event handler, sos.dll reports that the controls are elligable for collection, and indeed when I invoke GC.Collect (just for the debug purposes, of course) - they are collected ok. I wasn't able to reproduce this on a test app. The following (old) thread describes a similiar hypothetical situation, but there isn't a clear answer on this: http://groups.google.com/group/micro...4868e69bb0234a Thanks. |
#3
| |||
| |||
|
#4
| |||
| |||
|
#5
| |||
| |||
|
|
why is my application behaving weird with anonymous Event Handlers? |
#6
| |||
| |||
|
|
I have more to add to my original post. When using an anonymous delegate as an event handler, and using the add/remove accessors to register the event on an EventHandlerList, I observe (what is expected) that the original anonymous event handler is NOT removed from the list. This confirms what troubled me: using '-=' with an anonymous delegate, is worthless. If this is true, then using anonymous delegates as Event Handlers is a very risky business! They remain "forever" in the EventHandlerList/multicast-delegate's invocation list and do not allow GC on the referenced object (until the "child" UserControl is collected itself). |
#7
| |||
| |||
|
|
They're only useless in the situations where you *need* to remove event handlers. Most of the time when I write event handlers, the object "owning" the event becomes eligible for garbage collection at the same logical time as the target of the event handler, so it's not an issue. |
#8
| ||||
| ||||
|
|
My guess is that sometimes you are explicitly saving the event handler, and sometimes you are not. |
|
The -= doesn't care about delegate reference equality. It just matches instance reference and method reference. If (all) match, the delegate is removed. But with anonymous methods, |
|
// subscribe Event += delegate { // whatever }; // cancel, as in IDispose.Dispose Event Event -= delegate { // it doesn't help if you replicate the code exactly! }; |
|
is pointing to different code. Does // subscribe EventDelegate Registered = delegate { // whatever }; Event += Registered; // cancel, as in IDispose.Dispose Event Event -= Registered; work for you? |
#9
| |||
| |||
|
|
Hi Chris, thanks for your reply. I forgot to mention, that *I am* using the '-=' operator. If you'll read my other "additions" post (posted AFTER you have posted your reply...), then you'll see my thoughts regarding anonymous delegates and removing the delegate from the EventHandlerList/Invocation List. I've mentioned the Dispose, just in case someone would have replied 'use Dispose()'... Once again, just to make sure: using the '-=' operator on a 'non-anonymous' event handler works great. It is the anonymous event handler which makes all the trouble. And again - in my "additions" post you can see that I wasn't able to reproduce this on a test application, using anonymous delegates. This is what's so weird about it. |
#10
| |||
| |||
|
|
They're only useless in the situations where you *need* to remove event handlers. Most of the time when I write event handlers, the object "owning" the event becomes eligible for garbage collection at the same logical time as the target of the event handler, so it's not an issue. Correct. I was "generalizing". I have a question: If both "parent" and "child" are not referenced by anyone, except for the child containing the reference to the anonymous delegate in the "parent", aren't they supposed to be eligible for GC? This is what I expect it to be, and this is what my "reproducing code" behaves like. It's possible that I'm making a wrong assumption regarding my application, that when I replace the anonymous delegate to a non-anonymous delegate, they both become eligible for GC. But then again, it seems to be a fact. Any ideas? |
![]() |
| Thread Tools | Search this Thread |
| Display Modes | |
| |