问题
My wpf application has child windows that popup to show views to the user. The child windows are closed by executing CloseCommand
on the window's viewmodel, which sends a CloseWindowMessage
using itself as the token.
This is the viewmodel used:
public class ChildWindowViewModel : ViewModel
{
ICommand _closeCommand;
public ICommand CloseCommand
{
get
{
if (_closeCommand == null)
_closeCommand = new RelayCommand(DoClose);
return _closeCommand;
}
}
public void DoClose()
{
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
Messenger.Default.Send(new CloseWindowMessage(),this);
}
}
This is the method that shows windows:
protected void ShowWpfWindow(Window wpfWindow)
{
var dc = wpfWindow.DataContext as ChildWindowViewModel;
if (dc == null)
throw new ArgumentOutOfRangeException();
Action<CloseWindowMessage> action = (x) =>
{
wpfWindow.Close();
};
Messenger.Default.Register(wpfWindow, dc, action);
wpfWindow.Owner = MainWindow.Single;
wpfWindow.ShowInTaskbar = false;
wpfWindow.Show();
}
I have added the calls to GC.Collect()
and GC.WaitForPendingFinalizers()
for debugging purposes. These seem to cause the variable Action<CloseWindowMessage> action
to be garbage collected.
If I make Action<CloseWindowMessage> action
a field on the containing class:
Action<CloseWindowMessage> action;
protected void ShowWpfWindow(Window wpfWindow)
{
var dc = wpfWindow.DataContext as ChildWindowViewModel;
if (dc == null)
throw new ArgumentOutOfRangeException();
action = (x) =>
{
wpfWindow.Close();
};
Messenger.Default.Register(wpfWindow, dc, action);
wpfWindow.Owner = MainWindow.Single;
wpfWindow.ShowInTaskbar = false;
wpfWindow.Show();
}
The code works. I assume that the messenger maintains only a weak reference to the action, so that once execution passes out of ShowWpfWindow
the action may be garbage collected. By setting the action as a field on the class, I am tying its lifetime to that of its containing object. However, I don't want to do this as the lifetime of the containing object may be less than wpfWindow.
What sort of pattern should I adopt to ensure that the close action is not disposed?
来源:https://stackoverflow.com/questions/22536399/mvvm-light-message-recipient-action-being-garbage-collected