MVVM和异步任务,其生命周期长于页面的生命周期

时间:2013-02-05 18:30:55

标签: c# windows-phone-7 design-patterns windows-phone-8

MVVM方法很好并且已经建立。无论如何拍摄场景:您有一个应用页面,用户可以在其中启动一些长时间运行的任务。与本地和远程数据库的同步一样。此任务可能很长,只能优雅地中断。然后用户通过转到某个详细信息页面离开页面。取消长时间异步操作是没有意义的,因为应用程序仍在运行。但随后突然用户接到一个电话,以便停用应用程序。

在我(可能太原始)对MVVM的理解中,应该使用View Model来控制与Model的交互(特别是长时间的操作)。但View Model不需要知道应用程序生命周期事件,因为这会限制代码的可重用性(在Windows 8上没有像PhoneApplicationService这样的类)。看到这里的矛盾? VM启动操作,但不应用于取消操作。

当然,View可以承担处理终身事件的责任。因此关于应用程序停用的事件正在传播:View -> ViewModel -> (cancels long operation) -> Model。但是,如果用户已从View导航,并且该视图中启动的某些操作仍在运行,则无法再取消它 - View可以随时处理。

我只提出了一个想法,即在View Models中处理应用程序生命周期事件。但是,正如我之前所说,我不喜欢这种方法,因为它限制了View Models的可移植性。有人能提供更好的解决方案吗?

3 个答案:

答案 0 :(得分:4)

  

我只提出了一个想法,即在View Models中处理应用程序生命周期事件。但是,正如我之前所说,我不喜欢这种方法,因为它限制了View Models的可移植性。有人能提供更好的解决方案吗?

我实际上在这里看不到问题。在MVVM中,ViewModel传统上是将视图与模型联系起来的“粘合剂”。

为每个平台提供少量自定义ViewModel代码并不一定限制ViewModel其余部分的可移植性,特别是如果它被抽象并包含在每个平台的自己的项目中。

  

VM启动操作,但不应用于取消操作。

这强烈建议VM 取消它。如果VM创建了这些操作,它实际上拥有它们,这表明它应该管理它们的生命周期。

答案 1 :(得分:1)

我不确定这是否违反MVVM原则,但我只是这样想。

关于在VM中订阅PhoneApplicationService,是否有任何理由不采用这种方法,如

App - >视图模型

应用程序是虚拟机的所有者,如果应用程序告诉虚拟机通过视图对其虚拟机进行激活/停用,则虚拟机可以保持可重用性。但是当VM在其中订阅PhoneApplicationService时,它是不是真的,这意味着VM依赖于应用程序,这意味着VM和应用程序相互依赖并限制了可重用性?

关于长时间任务,如果它需要根据应用程序生命周期而不是页面生命周期生存,它可以在App范围内作为应用程序模型或可以从VM共享但不能在页面(视图)范围内共享的内容。

答案 2 :(得分:0)

您给出的描述告诉我,缺少抽象层。

特别是:

您的ViewModel当然可以启动影响模型的长时间运行事件, 但他们对这些长期活动没有任何所有权。这是完全正确的 是的,不应该被打破。如果你开始一个长期活动(和你的 数据库同步示例在这里非常好),那么模型应该 处理这个。

这里缺少的部分是我相信的模型。当有长时间运行 影响模型的任务,有一个单独的层来处理这些。 让我们称他们Transaction为了简单。

所以:你在模型领域开始长期运行的任务。然后是模型 执行此任务,如果一切正常并且没有被中断 一些用户或系统交互,然后可以应用任务数据 模型(或交易可以提交)。

如果用户或系统以某种方式取消任务,则根本不应该有任何数据 在模型中被改变。模型本身不会改变!

另一方面,如果模型成功更改,则ViewModel 应该得到通知,并且应该更新视图。但这只是一个 你在这里执行的两个主要执行分支。它就是 一,这是由MVVM和ViewModel实现已经处理的问题。

总体: 您的viewmodel应该启动并取消在模型上运行的任务,但它 特别是不需要控制它们的寿命。如果你出席 取消长途运行任务的可能性,你可以触发取消事件, 但是应该优雅地结束模型中的任务。