You probably think that the dot net framework being a kind of managed language doesn’t have memory leaks,

but in actual fact you can get something which is very similar to a memory leak using events and using

the observer design pattern.

So we’re going to take a look at a dot net specific design pattern, which is called Week event.

So the week event design pattern in particular shows up when you edit controls.

So when you make your own visual controls to be used in Winforms or WPF, for example.

So let me give you an example of what exactly the problem is and where it shows up.

Let’s suppose you have a class called Button.

So this class called Button has an event called Clicked because, well, guess what?

People can actually click the button and some sort of event may occur.

So you can do an event.

So we can do public event event handler and we can call it clicked.

And now, of course, we can also add a method called fire, which actually fires this particular event.

So we take clicked invoke and we invoke it with the reference to this as well as let’s just put in empty

default arguments here.

Okay, so this is our button.

Now let’s suppose we also have a window window like so now the window is going to take the button as

a constructor argument.

It’s not going to keep a reference to it, but it is going to subscribe to an event on the button.

So let’s make a constructor and this constructor and by the way, this should be window, not windows.

So let me just get rid of the extra letter here.

So this constructor takes a button and what it does is it subscribes to the event.

So it says, for example, Button dot clicked and it subscribes and maybe it makes even a separate method

for actually handling the button clicks.

So here we can write line button clicked and this is the window handler like so and we can also add

a destructor to window.

So I’m going to add a destructor just so that we can get some diagnostic information about when the

window is actually finalized.

So here I will write line window finalized like so.

Now here is the problem.

Here is the reason why the weak event pattern actually exists.

Let’s suppose that we make a window and a button.

So I’m going to make a button, var btn equals new button and in addition I will make the window.

So var window equals new window passing in the button.

And once again I made a mistake in the naming.

So let’s actually rename it to button like so.

So now that we have this kind of setup, what we can do is we can fire the event obviously, so we can

say button dot fire, for example.

But what we can also do is we can try to get rid of the window itself.

So what I can do is I can try and set the window to null.

So here I’m going to set setting, setting window to null.

And I will say Windows window rather equals null.

Now, you might be wondering, well, if we set the window to null and we collect, we perform the garbage

collection step, then certainly the finalizer here will kick in and we will get the window finalized

printed.

Well, guess what?

You won’t.

That will not happen.

And the reason it won’t happen is because we have subscribed to an event on the button and the button

is not dead yet.

The button is still alive and kicking.

So what this implies is that if I now fire the garbage collector, let’s actually implement a routine

for that.

So I’m just going to make a method here.

So what we’re going to do is we’ll do GC dot collect twice and in between we’ll wait for pending finalizes.

So we’re going to wait for pending finalizes here.

So as I fire the garbage collector, we can actually try to see whether the button is alive or not.

And first of all, let me just run this as is so that you can see that the button isn’t finalized.

So here is what’s happening.

Actually, I need to add a chunk of code to the beginning and ending of this particular method so that

we get to see where the GC is actually happening.

So I’m going to write line starting GC and then I will put here GC is done, so GC.

Is done like so, and that should be more illustrative.

So here is the problem.

We are starting GKE and GKE is done, but the window hasn’t been finalized even though we set it to

null.

So we set the window to null.

We collected the garbage, but the window wasn’t finalized.

It was only finalized when the application exited.

And this is deeply disappointing.

What this means is that you effectively have a memory leak, not a memory leak in the classical sense,

where you kind of lose the memory and you cannot appropriate this anymore, but you have an object which

is being kept from being garbage collected simply because it subscribes to an event on an object which

is still alive, which is this button here.

We can actually I can give you more proof that the window is alive by taking a weak reference to it

and checking whether it’s alive.

So the way this is done is I can take a reference so I can say var window ref equals new weak reference.

So the weak reference doesn’t increment the reference count, it just keeps a reference that doesn’t

affect the lifetime of the window.

So I will take the window reference here and then after I fire the GC, I can for example, write line.

Let’s write line.

Is the window alive after GC question mark and then we can check that reference.

We can check window ref dot is alive and if we execute this, you can see that we get a true, which

once again is very bad because look, we set the window to null.

It shouldn’t be alive after garbage collection, but it is precisely because the event is leaking.

So what happens if you want to fix this particular problem?

And this is mainly a problem for control developers.

Like I said, what happens if you want to fix this problem is that since Dotnet 4.5, you actually have

a very nice class called Week Event Manager, which kind of takes care of everything for you.

And in order to start using it, you have to get away from the plus equals approach.

So certainly one of the approaches you could take is you could add some sort of idisposable and in the

dispose method you would add button dot collect minus equals button on clicked.

So that is one way that it could work.

But a more kind of proper way, shall we say, is to use the week event manager.

So let’s do exactly that.

Now the week event manager exists in the Windows Base Assembly.

So first of all, we need a reference.

So this is in Windows base and as a consequence you can probably guess it’s not going to be available

in Dotnet core or anything like that, but we have it on the proper net framework.

So here’s how you use it.

You simply get rid of the invocation here, get rid of the plus equals and you replace it with something

different.

You take the week event manager.

The generic version and the generic version takes two arguments.

The first argument is what you’re listening to.

In this case, we’re listening to the button.

And the second is the type of the event arguments.

So here we’re just using event args.

That’s what we’re going to put in.

So you make week event manager, you put a dot and you say add handler, add handler like so and here

you add the source, which is the button.

You also add the name of the event.

In our case, it’s clicked, I believe.

And finally you add the handler and we’ve already got the handler.

So in our case it’s button on clicked.

So let’s execute the same program once again.

And now we’re going to see a slightly different result.

Notice that as we start the GC, the window which we set to null is in fact finalized.

And the reason why it’s finalized is because we now have a proper week way of handling events and in

fact handling the situation where somebody who subscribes to an event has been garbage collected.

So this is an improvement and this is called the week event pattern and it’s implemented by the Week

event Manager class.

So from Dotnet 4.5 onwards, you have this wonderful class which will basically do everything for you

and there is no need to write any additional code Now before Dotnet 4.5.

The setup is a bit more complicated and you are welcome to look online on resources such as Codeproject,

where the alternative approaches to the week event pattern are outlined as well.

Play Play Stop Play Play Play Play Play Start Play information alert