Thursday July 30th

Wednesday July 29th

Solving the Problem with Events: Weak Event Handlers

One of the greatest frustration of working with delegates and events is that they can potentially cause memory leaks if they aren't unhooked. In this article, we will solve this problem in a variety of ways to get the best performance, memory use and syntax.

2 comments

Article is a better resource for the inner workings of the CLR and GC than for preventing event-related memory leaks.

Hello Dustin.
Weak events, or should I say the lack of them causing me headache as well.
That's why I was extremely pleased to stumble upon your excellent blog. However, I got different measurements, which make using LCG a very good alternative only slightly slower than using unbound delegates:
[normal]:
Subscribing one event handler takes about 0.55988 microseconds
Firing one event handler takes about 0.39475 microseconds
[weak by reflection]:
Subscribing one event handler takes about 19.2845 microseconds
Firing one event handler takes about 19.66328 microseconds
Subscribing is 34.4440 times slower
Firing is 49.8120 times slower
[weak by LCG]:
Subscribing one event handler takes about 91.05281 microseconds
Firing one event handler takes about 0.57962 microseconds
Subscribing is 162.6292 times slower
Firing is 1.4683 times slower
[weak by unbound delegate]:
Subscribing one event handler takes about 38.31363 microseconds
Firing one event handler takes about 0.56384 microseconds
Subscribing is 68.4319 times slower
Firing is 1.4283 times slower

I subscribe and fire 10000 times and use the Stopwatch class to measure the times.

Here is how I measure the times:

public double Subscribe(int count)
{
EventProvider provider = new EventProvider();
Stopwatch sw = new Stopwatch();
for (int i = 0; i < count; ++i)
{
sw.Start();
provider.MyEvent += new WeakEventHandler<EventArgs>(MyEventHandler);
sw.Stop();
provider.Reset(); // clears the event delegate
}
return (1000 * sw.Elapsed.TotalMilliseconds) / count;
}

public double Fire(int count)
{
EventProvider provider = new EventProvider();
provider.MyEvent += new WeakEventHandler<EventArgs>(MyEventHandler);

Stopwatch sw = new Stopwatch();
for (int i = 0; i < count; ++i)
{
provider.Fire(sw);
}
return (1000 * sw.Elapsed.TotalMilliseconds) / count;
}

Am I doing something wrong or is LCG indeed a very good option?
Thanks.

Commenting on Stories is limited for now and will open up to those recommended by the community. Learn how
Loading DotNetKicks...
brought to you by the Kicks Network