MVVM Light: How to Unregister Messenger

I like MVVM Light Messenger and its flexibility, but I experience a memory leak when I forget to explicitly unregister recipients (in Silverlight 4).

The reason is explained here , but I'm fine, as I find it good practice to explicitly unregister recipients, rather than relying on the use of weak links in Messenger. The problem is that it's easier said than done.

  • ViewModels are simple: you usually have full control over your life cycle and you can just Cleanup() them when they are no longer needed.

  • Views , on the other hand, are more complex because they are created and destroyed using DataTemplates. E.g. you can think of ItemsControl with MyView as a DataTemplate bound to an ObservableCollection<MyViewModel> . MyView are created / built by the binding mechanism, and you have no good way to manually call Cleanup () on them.

I have a solution, but I would like to know if he has a decent sample or if there are better alternatives. The idea is to send a specific message from the ViewModel to inform the related View (s):

 public class MyViewModel : ViewModelBase { ... public override void Cleanup() { // unregisters its own messages, so that we risk no leak Messenger.Default.Unregister<...>(this); // sends a message telling that this ViewModel is being cleaned Messenger.Default.Send(new ViewModelDisposingMessage(this)); base.Cleanup(); } } public class MyView : UserControl, ICleanup { public MyView() { // registers to messages it actually needs Messenger.Default.Register<...>(this, DoSomething); // registers to the ViewModelDisposing message Messenger.Default.Register<ViewModelDisposingMessage>(this, m => { if (m.SenderViewModel == this.DataContext) this.Cleanup(); }); } public void Cleanup() { Messenger.Default.Unregister<...>(this); Messenger.Default.Unregister<ViewModelDisposingMessage>(this); } } 

Therefore, when you call Cleanup () on the viewModel, all views that use it as a DataContext will also do their local cleanup ().

What do you think? Am I missing something?

+42
c # silverlight mvvm mvvm-light
Mar 10 '11 at 8:12
source share
3 answers

The ViewModelLocator class helps you maintain a centralized repository for your viewmodels. You can use this class to manage new versions and clean up old ones. I always refer to my viewmodel from the view through the locator, so I always have code that I can run to manage these things. You can try this.

In addition, I use the Cleanup method to call Messenger.Unregister(this) , which clears all links from the messenger for this object. You should call .Cleanup () every time, but this is life :)

+6
Jun 25 '11 at 18:11
source share

I did not use MVVM Light (although I heard great things), but if you want the Messenger implementation to use WeakReferences, check if Messenger is enabled http://mvvmfoundation.codeplex.com/ .

+1
Apr 08 2018-11-18T00:
source share

MVVM Light Messenger uses WeakAction (WeakReference). Therefore, you do not need to explicitly unregister.

0
Nov 01 2018-11-11T00:
source share



All Articles