Memory Leaks in the PresentationModel classes

Topics: Prism v2 - WPF 3.5
Mar 8, 2009 at 10:30 PM

The PresentationModel classes (e.g. WatchListPresentationModel) in the StockTrader RI collaborate with services to retrieve the data that is shown to the user. Some of these services (e.g. WatchListService) provide events so that the PresentationModel gets informed when the data changes.

When the PresentationModel adds an event handler to the service event then it couples its lifecycle to the one of the service. Services are often implemented as singletons whereas the View and its associated PresentationModel just lives as long the user edits the data in the View.

Example: WatchListPresentationModel

this.watchList = watchListService.RetrieveWatchList();

this.watchList.CollectionChanged += delegate
{
    this.PopulateWatchItemsList(this.watchList);
};

Because the PresentationModel adds an event handler, the internal event implementation of the service keeps a reference back to the PresentationModel. The garbage collector will never be able to collect the PresentationModel or the View object as long the service is alive.

Solutions:
1. Use the EventAggregator of the CAL libraries
2. Use the WeakEvent  Pattern (see http://msdn.microsoft.com/en-us/library/aa970850.aspx)

The first one cannot be used in all scenarios. Thus, I prefer the second solution.

I believe this concept is very important and so I provide a PresentationModel base class that supports this pattern in my project: http://www.codeplex.com/CompositeExtensions

Do you have other ideas to solve this memory issue?
jbe

Mar 9, 2009 at 7:56 PM

Hi

 

While the WeakEvent pattern is a good solution for this problem for communication within modules , it might not be the best approach for communication between modules. This is because to subscribe to an object, you need a direct reference to that object. This is where the EventAggregator provided by CAL comes into play, since the publisher and the handler can be in different modules and the expected behavior will still be obtained, thus avoiding having hard references.

                    

Could you share the particular scenario where the EventAggregator is not usable?

 

For more information about the EventAggregator service and communication in Composite Applications you can check the following topics:

·         Communication

·         Event Aggregator

 

Please let me know if this helps.

 

Damian Schenkelman

http://blogs.southworks.net/dschenkelman

Mar 15, 2009 at 6:04 PM
Hi Damian!

You are absolute right that the EventArggregator solves the problem of loose coupling of publisher and subscriber.

My scenario:

In my case I have to wire business objects with the UI together. Both layers are implemented within the same module. The business objects implement the INotifyPropertyChanged interface so that the WPF binding gets notified when the associated business object has changed. The WPF binding implementation uses the WeakEvent pattern to prevent memory leaks.

When I’m using the PresentationModel pattern then the UI binds to the PresentationModel class which itself “binds” to the business object class. The PresentationModel might need to listen to property change notifications of the business object. In such a case the PresentationModel should use the WeakEvent pattern in the same way as the WPF binding implementation does to prevent memory leaks.

jbe
Mar 24, 2009 at 2:47 PM
I have found another solution in the MSDN Magazine, February 2009: “WPF Apps With The Model-View-ViewModel Design Pattern, Josh Smith” (http://msdn.microsoft.com/en-us/magazine/dd419663.aspx)
 
In his sample project he provides a base class for the Model-View-ViewModel pattern. This base class “ViewModelBase” implements the IDisposable interface. He uses the Disposable pattern to unwire the ViewModel implementation from the consumed events so that the garbage collector is able to collect the ViewModel object.
 
I prefer the WeakEvent pattern over the Disposable pattern because it’s more the WPF way to consume events. However, both solutions prevent memory leaks in our M-V-VM or PresentationModel implementations.
 
jbe