I'm having a problem where an application I'm worki开发者_如何学Gong on has memory leaks. Experience has taught me that one of the first places garbage collected languages experience memory leaks is dealing with subscribing to events and failing to unsubscribe them later. The second has to do with storing static state. I'm new to C# and have been frustrated by the opaque event type.
We've caught a few double subscription errors through luck of the draw, but the application really uses events for a number of things. While we are well aware of the principle of unsubscribing everything you subscribe to, there's still memory leaks. I'd like to systematically determine what's subscribed to what.
Edit:
Thank you for the pointer to the GetInvocationList()
method. I'm trying to create a debug harness that will dump the results dynamically. Problem is that the solutions I found worked in .Net 2, but no longer in .Net 3.5. Essentially, the tell you to get the corresponding FieldInfo for the EventInfo (reflection, GetField and GetEvents respectively). However, in .Net 3.5 there is no corresponding FieldInfo, and EventInfo won't let me get the invocation list.
I just want to dump the list of events and their InvocationList for debugging purposes.
Try to use an method on the event
called GetInvocationList
.
This will return an array of delegates that is subscribing to the event.
The array will contain the delegates in the order they where added. This can also be used to single out and invoking specific delegates from the list, whereas calling the event.Invoke
method will invoke them all (but only give you the return value of the last delegate called)
You are certainly right-on suspecting event-subscription as a cause to memory 'leaks.' Years ago we tracked down a problem where an application-wide static object was subscribing to ASP.NET page events - you can guess what happened there.
Another way to tackle this is from the publisher's perspective. It might not be convenient to get all your subscribers to UNsubscribe, but if the publisher needs to be destroyed/go out of scope maybe it can be triggered to set all its events to null - effectively unsubscribing everyone and breaking the loops.
If the publisher has a longer lifetime and is the thing keeping other objects alive, you may have to do the GetInvocationList thing suggested earlier. But I would consider that only for debugging the problem - finding out who's hanging on to events when they shouldn't.
Last-resort you could consider some WeakReferenced-based custom event subscription mechanism.
精彩评论