I need to remove all event bindings for every object in my system. There are thousands of objects that are holding events and this is causing memory leaks. I'm under a serious time constraint to get this sorted so I'm wondering if there's a way to recursively loop through an object hierarchy to remove the event bindings?
-
Winform? WPF? Asp.net? Silverlight? Shall I continue? – gdoron Feb 26 '13 at 16:41
-
C#. Custom objects, custom events. – DaveDev Feb 26 '13 at 16:52
-
1It seems that you have a big problem andhave to rewrite all classes in your system. Or drop your system off and write new one from the grounds. – Kirill Bestemyanov Feb 26 '13 at 17:14
-
Couldn't agree more with @KirillBestemyanov, in the process, also drop dinosaur winforms and use a contemporary XAML-based UI technology so that you don't have to deal with events anymore. – Federico Berasategui Feb 26 '13 at 18:59
-
Have you read this http://stackoverflow.com/questions/91778/how-to-remove-all-event-handlers-from-a-control ? – Dzienny Feb 26 '13 at 22:48
2 Answers
NOTE: This is all really hacky stuff, and I do not condone its usage!
That said...yeah, you can. Kinda.
Say you've got a class Foo
:
public class Foo
{
public event EventHandler SomeEvent;
public void Trigger()
{
if(SomeEvent != null)
{
SomeEvent(this, new EventArgs());
}
}
}
We new one of these up, and connect to the event in a variety of ways:
public class Bar
{
public Bar(Foo foo)
{
foo.SomeEvent += FooEvent;
}
public void FooEvent(object sender, EventArgs e)
{
Console.WriteLine("Bar.FooEvent!");
}
}
var foo = new Foo();
var bar = new Bar(foo);
foo.SomeEvent += (o,e) => Console.WriteLine("SomeEvent");
Console.WriteLine("Normal");
foo.Trigger();
Output:
Normal
Bar.FooEvent!
SomeEvent
All normal so far, right?
Now - the nastiness that is allowable via Reflection:
First, we'll need references to the EventInfo
and the remove
method for the event:
var theFooEvent = foo.GetType().GetEvent("SomeEvent");
var theFooRemover = theFooEvent.GetRemoveMethod(true);
Next, we'll abuse Expressions
a bit to get the "present value":
var exp =
System.Linq.Expressions.Expression.PropertyOrField(
System.Linq.Expressions.Expression.Constant(foo),
"SomeEvent");
var member = exp.Member;
var rtMember = (member as FieldInfo).GetValue(foo) as EventHandler;
We're halfway there - now to blow away all the existing handlers:
var handlers = rtMember.GetInvocationList();
foreach(var handler in handlers)
{
theFooRemover.Invoke(foo, new[] { handler });
}
There...that's it! Further calls to Trigger
won't actually do anything:
Console.WriteLine("Post hackery");
foo.Trigger();
Output:
Post hackery

- 16,584
- 3
- 43
- 55
Nasty. It doesn't look possible with reflection unless you know the names of the event handlers; is it possible to modify the Dispose methods of your objects to remove their members' event handlers?

- 1,698
- 2
- 20
- 21
-
It might be, but that'll take a lot of code modification. I was hoping for a quick-n-easy approach. Unfortunately there might not be one of those! – DaveDev Feb 26 '13 at 17:11
-
It kind of surprises me that there isn't (or doesn't seem to be). – Steve Westbrook Feb 26 '13 at 17:12