0

我只需要一点帮助来阐明 Messenger 类如何与 MVVM-Light 中的 ICleanup 一起工作。我正在使用 Mvvm-Light v4 在 VB.Net 中创建 WPF 4 应用程序。

我有一个信使,它注册从我创建的 NavigationService 类发送的消息,如下所示:

这是在名为 ClientListViewModel 的 ViewModel 中的注册

 ''register for messages
  Messenger.[Default].Register(Of INavigationService)(Me, "NavigationStart", False, AddressOf HandleParentChildNavigate)

这接收 NavigationService 类并根据与此问题无关的其他逻辑对其执行检查。

在我的 NavigationService 类中触发导航事件时发送消息,如下所示

''Send message that navigation has been requested
Messenger.Default.Send(Of INavigationService)(Me, "NavigationStart")

如果我的接收类(在本例中为 ClientListViewModel)有数据验证错误,这允许我取消导航事件,并将焦点返回到有错误的记录。这一切都很好。

我的问题是,我在哪里以及如何取消注册该消息。我知道我需要这样做以避免在我阅读其他帖子时出现内存泄漏。我看到了类似以下的内容:

Public Overrides Sub CleanUp()
    Messenger.Default.Unregister(Me)
End Sub

此清理位于接收消息的同一视图模型 (CientListViewModel) 中。

所以我有三个问题:

  1. 我什么时候应该调用这个清理方法

  2. ViewModelLocator 有没有办法在应用程序关闭时取消注册所有消息收件人?

  3. 这个问题不太相关,但我也希望得到一些帮助,我如何判断我是否由于未注册的消息收件人而出现“内存泄漏”?

谢谢你的时间

4

2 回答 2

4

何时应该“清理”视图模型取决于您的应用程序和视图模型的使用情况。例如,我处理带有选项卡式界面的应用程序。当用户关闭选项卡时,应用程序会在代表该选项卡的视图模型上调用清理(它本身会通过其视图模型并在它们上调用清理)。所以一般规则 - 一旦你不再需要视图模型 - 你应该清理它(关闭子窗口,选项卡等)至于其他问题:

2)如果你清理你的视图模型,关闭应用程序确实无关紧要。在关闭所有内存时,所有内存都将被释放,并且您不会出现内存泄漏 :)

3)您应该检查应用程序内存使用情况。在我们的应用程序中,我们遇到了严重的内存泄漏问题(实际上仍然存在但不是那么大)。我们确定我们可能会通过内存跟踪泄漏:打开/关闭了许多选项卡,调用GC.Collect()- 但内存使用量并没有下降。我们开始使用 WinDbg 跟踪内存泄漏,发现确实有很多地方我们没有从 Messenger 注销收件人。此外,我们正在使用绑定到 CommandManager 的旧版本的 MVVM Light,因此我们也遇到了 RelayCommands 的问题。

道德是-您应该考虑在编程期间清理资源,因为以后找到并修复它可能会很痛苦。

于 2013-02-05T09:03:38.570 回答
1

我没有在 MVVM-Light 中使用过 Messenger,所以我不知道是否有固有的清理方法。以下是对这些问题的一些一般性答案:

  1. 当您不再需要了解消息或不再需要您的视图模型时,您应该进行清理。如果 Navigate 未取消,您的 ViewModel 是否会再关心 Navigate 消息(即它是否被卸载或者它支持的视图是否消失)?如果是这种情况,那么您可以在收到导航命令并确定可以导航时取消注册。

  2. 这个我不知道。但是在应用程序关闭时,这无关紧要(对于托管对象,请参见下文)。

  3. 当应用程序关闭时,您不必担心托管对象的这些内存泄漏,当整个应用程序域终止时,任何未引用的对象都将被丢弃。如果您引用了非托管资源,这是另一回事。

于 2013-02-01T17:56:58.277 回答