The WeakReference class that exists since .NET 1.0 can be used to wrap an object while not being the one keeping it alive. This may be useful in an “Observer” pattern scenario, where a client registers for some notification, but “forgets” to unregister. That means that with a normal reference, even if the client is no longer needed, it keeps getting notifications because the server object keeps a strong reference to the client.
Here’s a simple example:
class BasicSubject {
List<INotify> _clients = new List<INotify>();
public void Attach(INotify client) {
_clients.Add(client);
}
public void DoSomething() {
// notify clients
foreach(var client in _clients)
client.Update();
}
public void Detach(INotify client) {
_clients.Remove(client);
}
}
A simple client (observer) may be implemented like so:
class MyObserver : INotify {
public void Update() {
Console.WriteLine("Update received!");
}
}
Now, we can test:
static void TestBasicSubject() {
var subject = new BasicSubject();
var observer = new MyObserver();
subject.Attach(observer);
subject.DoSomething();
// not interested anymore
observer = null;
subject.DoSomething(); // still notified
GC.Collect();
subject.DoSomething(); // still notified yet!
}
How many times would the observer be notified? Three times. The call in line (12) to GC.Collect is not enough, because the client is not garbage – the subject holds a strong reference to the client.
Read more: Pavel's Blog
0 comments:
Post a Comment