Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you find out what is subscribed to an event in C#?

I'm having a problem where an application I'm working 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.

like image 898
Berin Loritsch Avatar asked Dec 09 '10 15:12

Berin Loritsch


2 Answers

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)

like image 116
Øyvind Bråthen Avatar answered Oct 26 '22 14:10

Øyvind Bråthen


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.

like image 23
n8wrl Avatar answered Oct 26 '22 12:10

n8wrl