是异步/伺机在MVVM没用?没用、MVVM

2023-09-03 02:11:15 作者:醉翁著踞

在MVVM其中的ViewModels更新通过INotifyPropertyChanged的事件的看法,似乎没有要大大室/等待的异步的很酷的功能;执行对调用者捕获同步环境的延续。

In MVVM where the ViewModels update the Views via INotifyPropertyChanged events, there doesn't seem to be much room for the cool feature of async/await; executing the continuation on the captured synchronization context of the invoker.

那么,如果是这样的话,那么谁将会实际使用异步的功能/等候在现代的UI基于应用程序?在这样的背景下,谁也可以指什么模式,如MVC-变化。

So, if this is the case, then who will actually use the features of async/await in a modern UI based app? In this context, "who" can also mean what pattern, e.g. MVC-variation.

我能想到下面是使用TAP的好办法

I can think of the following as a good way of using TAP

ViewModel.Age
{
  set {
    await Model.SetAge(value);
    NotifyPropertyChanged("Age");
  }
}

不过,在对捕获syncContext此运行,并不能真正帮助了很多。 其实,我们可以把所有这些模型来代替。

however, having this run on the captured syncContext, does not really help out much. Actually, we could put all this in the model instead.

Model.Age
{
  set {
    await SetAge(value);
    NotifyPropertyChanged("Age");
  }
}

现在,我们真的很喜欢syncContext不被捕获的。

and now, we would really like the syncContext NOT to be the captured one.

推荐答案

其实,有 INotifyPropertyChanged.PropertyChanged 在UI同步背景下提出的的需要数据绑定。

Actually, having INotifyPropertyChanged.PropertyChanged raised in the UI synchronization context is required for data binding.

异步 / 等待不要强迫你做之间的属性的区别(这再present的当前状态,并随时同步)和命令的(这将重新present行动,可能是同步或异步)。物业getter和setter的不能的被异步,所以你的例子code与异步集不是一个可行的方法。

async / await do force you to make a distinction between properties (which represent the current state and are always synchronous) and commands (which represent actions and may be synchronous or asynchronous). Property getters and setters cannot be async, so your example code with an "async set" is not a possible approach.

异步使异步命令。您可以使用命令绑定异步处理路由命令,或通过一个异步委托给一个 DelegateCommand ,或使用自己的的ICommand 的实施。无论你做的方式,你最终与异步无效命令事件处理程序。

async enables asynchronous commands. You can use command binding to asynchronously handle routed commands, or pass an async delegate to a DelegateCommand, or use your own ICommand implementation. Whichever way you'll do it, you end up with an async void command event handler.

一个现实的例子是,在VM属性中设置对M属性内存,并有一个 SaveCommand 异步处理程序。这是常见的有异步处理程序有一个额外的虚拟机属性( SaveInProgress 互动,或者一个共同的与其他异步处理程序共享),这样用户界面可以做出适当的反应,当命令正在进行中(通常至少造成 CanExecute 返回)。

A realistic example is to have the VM properties set the M properties in-memory, and have a SaveCommand with an async handler. It's common to have async handlers interact with an additional VM property (SaveInProgress or maybe a common Busy shared with other async handlers) so that the UI can respond appropriately when the command is in progress (usually at least causing CanExecute to return false).

所以,你的异步处理程序最终看起来是这样的:

So your async handler ends up looking something like:

private async void SaveCommandExecute()
{
  try
  {
    // Set VM property; updates View appropriately.
    Busy = true;

    // Do the actual saving asynchronously.
    await Model.SaveAsync();
  }
  catch (Exception ex)
  {
    // Update the VM with error information.
    Error = ex.Message;
  }
  finally
  {
    // Let the VM know we're done.
    Busy = false;
  }
}

private void SaveCommandCanExecute()
{
  return !Busy;
}

请注意,该虚拟机属性( 错误)在所拍摄的UI同步环境进行更新。

Note that the VM properties (Error and Busy) are updated in the captured UI synchronization context.

这说明的核心概念异步 MVVM:命令可能是异步,但性能(如)始终重新present的当前状态。

This illustrates the central concept of async MVVM: commands may be async, but the properties (such as Busy) always represent the current state.

如果您要添加异步到现有的MVVM应用程序,你会发现自己与几个附加属性说明业务也可能进度更新(例如,完成百分比) 。根据您的应用程序,你可以在同一时间允许多个异步操作。你需要考虑到这一信息添加到您的意见很好的方式;我觉得这是最具挑战性的部分异步 MVVM应用程序。

If you're adding async to an existing MVVM app, you'll find yourself with several additional properties indicating business and possibly also progress updates (e.g., percent complete). Depending on your application, you may permit multiple asynchronous operations at the same time. You'll need to think of good ways to add this information to your Views; I find this to be the most challenging part of async MVVM apps.

 
精彩推荐
图片推荐