Mvvm Light message recipient action being garbage collected

ぃ、小莉子 提交于 2019-12-24 05:13:09

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!