EventAggregator - duplicate subscriptions

Topics: Prism v4 - WPF 4
Dec 17, 2013 at 12:42 PM
Hi,

I'm working on a WPF application with Prism.

I have a wrapper around IEventAggregator similar to the one described here: http://rachel53461.wordpress.com/2011/06/05/communication-between-viewmodels-with-mvvm/

I have a multi step process with a progress tab. As I navigate through the process, the progress bar gets populated. As I complete a step, I dispatch a message to the progress tab so that it can update progress accordingly. First way round this works fine. Once the process is complete, I close the window and send user to the home screen.

I then start the same process again and this is where the problem starts. View models subscribe to the events, however, the old subscriptions are still alive, so as I navigate through the steps, the same message gets published twice, which is a massive problem.

I use weak references as I expect Prism to dispose of old subscriptions.

If I were to unsubscribe from all the events, I would have to do this at the very end of the process (final confirmation screen). This is not feasible as final confirmation screen isn't aware of all the components (view models) that are already subscribed. I would also argue and say that it shouldn't be aware of these components as it makes the design tightly coupled.

I have tried implementing IDisposable on the view models, but it's not being called.

I have also tried implementing a destructor and then manually calling GC.Collect() - this also did nothing.

I have also read the following blog post: https://compositewpf.codeplex.com/workitem/4925 - it says that subscriptions don't get cleared unless the filter is specified. This didn't help either.

With regards to infrastructure, my event broker (wrapper around IEventAggregator) gets injected by structure map on the application startup. The same instance of the event broker is used throughout the application.

View models get injected into the window. I then set window's data context to the view model that has been injected.

I currently don't use any other feature of Prism, just the event aggregator.

I'm unable to post the project as it's very large and has many dependencies (both hardware and software). I've spent over a day on this so far and I would be most grateful for any advise/suggestions.

Thank you
Dec 17, 2013 at 3:34 PM
Hello vikpea,

Based on my understanding there wouldn't be an exact time or interval of time where the Garbage Collector would execute. Therefore the ViewModels could remain alive the application lifetime, and its Event's weak reference would still be handled.

Regarding the destructor you implemented for calling the Garbage Collector, I suggest you to verify if strong references were held like the registration of the ViewModels in the corresponding Region.

Nevertheless, a possible workaround without using strong references would be by raising an event after the process ended in order to unsubscribe() each ViewModel's Subscription. You could accomplish this by subscribing to an event on each process's ViewModel, which its EventHandler would unsubscribe its proper event of progress update.
This way the old Event Subscriptions would be removed, although the ViewModels objects may still be alive.


I hope this helped you,

Gabriel Ostrowsky
https://blogs.southworks.net/gostrowsky
Marked as answer by vikpea on 12/17/2013 at 8:19 AM
Dec 17, 2013 at 4:19 PM
Hi Gabriel,

Thank you for your reply.

I don't yet use regions, but I will have a look into them.

Your second suggestion was a very good idea. I have implemented this and it works. Thanks a lot for that. I will now try to make the solution a bit more generic as it appears a little hacky to me.