MVVM和异步任务的生存期超过page';的一生

本文关键字:page 一生 异步 任务 生存期 MVVM | 更新日期: 2023-09-27 17:57:41

MVVM方法很好,而且建立得很好。然而,想象一下场景:您有一个应用程序页面,用户可以在其中启动一些长期运行的任务。类似于本地和远程数据库的同步。这项任务可能很长,只能优雅地中断。然后用户通过转到一些详细信息页面离开页面。取消那个长时间的异步操作是没有意义的,因为应用程序仍在运行。但随后用户突然接到一个电话,所以该应用程序被停用。

在我对MVVM的理解中(可能过于原始),视图模型应该用于控制与模型的交互(尤其是长操作)。但是视图模型不需要知道应用程序生存期事件,因为这会限制代码的可重用性(在Windows8上没有PhoneApplicationService这样的类)。看到矛盾了吗?VM启动操作,但不应用于取消操作。

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

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

MVVM和异步任务的生存期超过page';的一生

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

事实上,我认为这里没有问题。在MVVM中,ViewModel传统上是将视图与模型联系起来的"粘合剂"。

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

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

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

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

关于在虚拟机中订阅PhoneApplicationService,有什么理由不采取这种方法吗

应用程序->ViewModel

应用程序是虚拟机的所有者,如果应用程序告诉虚拟机通过界面激活/停用,就像视图对其虚拟机所做的那样,虚拟机可以保持可重用性。但一旦虚拟机在其中订阅了PhoneApplicationService,这不是真的吗?这意味着虚拟机对应用程序有依赖性,这意味着VM和应用程序相互依赖,并限制了可重用性?

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

您给出的描述向我表明,缺少抽象层。

特别是:

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

我相信这里缺少的部分在模型中。当有长跑时影响模型的任务有一个单独的层来处理这些任务。为了简化起见,让我们称它们为Transaction

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

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

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

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