Recipient actions being garbage collected?

Mar 20, 2014 at 3:33 PM

I have a method I am using to show child windows in my application. For each child window, it sets up a recipient to respond to Close messages from that window. Here is the code:
protected void ShowWpfWindow(Window wpfWindow)
    var dc = wpfWindow.DataContext as ChildWindowViewModel;
    if (dc == null)
        throw new ArgumentOutOfRangeException();

    Action<CloseWindowMessage> action = (x) => 
    Messenger.Default.Register(wpfWindow, dc, action);

    wpfWindow.Owner = MainWindow.Single;
    wpfWindow.ShowInTaskbar = false;
The problem is that the action is being garbage collected - I assume this is because it's a local variable to the calling method and the messenger doesn't hold a strong reference to it. This means that once the method is finished, the action is liable for garbage collecting.

What sort of pattern should I use to avoid this issue? This is actually a bit annoying as I quite like defining my application behavior with little anonymous functions, so perhaps I should change the implementation of Messenger? Or do you think it's a bad idea to define actions like this?

I've gone into some more detail about the problem in my stackoverflow question: mvvm light message recipient action being garbage collected.

I would appreciate any comments you might have.
Mar 24, 2014 at 3:41 PM
Edited Mar 24, 2014 at 3:43 PM
I wrote another stackoverflow post that includes a concise sample application that reproduces the problem. It turns out the issue is with the line wpfWindow.Close() - somehow, referencing variables from the containing method scope seem to tie the lifetime of the action to that scope, so that the action can be garbage collected whenever. Weird!

Here is the question: Strange behavior with actions, local variables and garbage collection in mvvm light messenger

I guess something strange is happening with all the WeakReferences and WeakActions in the Messenger implementation, but I don't know what exactly.

This is the first time I've hit a problem with C# that's really left my stumped in a while. I guess I don't know my way around garbage collection and memory management as well as I should!
Mar 27, 2014 at 4:18 PM
Jon Skeet gave a rather nice answer outlining the cause of this issue. It seems to relate to technicalities of how the compiler compiles anonymous functions.


I'm going to try working with MVVM Light's implementation of WeakActions and similar to see if I can resolve this. Perhaps the developer(s) of MVVM Light might also want to consider this case? I'm sure that the use of anonymous functions with variable capture is quite common for message handlers when using MVVM Light, so this issue may be causing lots of subtle bugs to appear.