gpt4 book ai didi

c# - MVVM 光 : how to unregister Messenger

转载 作者:IT王子 更新时间:2023-10-29 03:55:46 29 4
gpt4 key购买 nike

我喜欢 MVVM Light 的 Messenger 及其灵 active ,但是当我忘记显式注销收件人时(在 Silverlight 4 中),我遇到了内存泄漏问题。

原因解释here ,但我对此表示满意,因为我认为无论如何显式注销收件人而不是依赖 Messenger 对弱引用的使用是一种很好的做法。问题是说起来容易做起来难。

  • ViewModels 很简单:您通常可以完全控制它们的生命周期并且可以 Cleanup()在不再需要它们时使用它们。

  • 另一方面,
  • Views 比较棘手,因为它们是通过 DataTemplates 实例化和销毁的。对于前。你可以想到一个ItemsControlMyView作为 DataTemplate,绑定(bind)到 ObservableCollection<MyViewModel> . MyView控件由绑定(bind)引擎创建/收集,您没有好的方法手动调用它们的 Cleanup()。

我有一个解决方案,但想知道它是否是一个不错的模式或者是否有更好的替代方案。这个想法是从 ViewModel 发送一个特定的消息来告诉相关的 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);
}
}

因此,当您在 viewModel 上调用 Cleanup() 时,所有使用它作为 DataContext 的 View 也将执行它们的本地 Cleanup()。

你怎么看?我是否遗漏了一些明显的东西?

最佳答案

ViewModelLocator 类有助于为您的 View 模型保持集中存储。您可以使用此类来帮助管理新版本和清理旧版本。我总是通过定位器从 View 中引用我的 View 模型,所以我总是有可以运行的代码来管理这些东西。你可以试试看。

此外,我使用 Cleanup 方法调用 Messenger.Unregister(this),它会清除该对象的 Messenger 中的所有引用。您必须每次都调用 .Cleanup(),但这就是生活:)

关于c# - MVVM 光 : how to unregister Messenger,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5257002/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com