【问题标题】:await for Command.Execute with or without async Action等待带有或不带有异步操作的 Command.Execute
【发布时间】:2019-07-21 05:58:51
【问题描述】:

我遇到了一个奇怪的案例,我被困住了。

我有一个 Popup View + ViewModel 作为里面的按钮。 Popup 从其他视图获取 Command 以执行按钮。

现在,我想在单击后立即禁用该按钮,运行命令然后将其禁用。

这就是我现在拥有的:

PopupViewModel

public override Task InitializeAsync(object navigationData)
{
    PopupModel model = (PopupModel) navigationData;
    ...
    _mainActionCommandToRun = model.MainActionCommand;
    ...
    return base.InitializeAsync(navigationData);
}

private void OnMainActionCommand(object obj)
{
    MainActionCommand.CanExecute(false);
    _mainActionCommandToRun.Execute(null);
    MainActionCommand.CanExecute(true);
}

一些查看如何使用弹出窗口

await DialogService.ShowPopupAsync<PopupViewModel>(new PopupModel
{
    ...
    MainActionCommand = new Command(
        () =>
        {
            DoSomeThing();
        })
});

这个案例就像一个魅力。当分配给命令的操作是异步的时,它会变得复杂。

一些带有异步操作的视图

await DialogService.ShowPopupAsync<PopupViewModel>(new PopupModel
{
    ...
    MainActionCommand = new Command(
       async () =>
        {
            await DoSomeThing();
        })
});

在这种情况下,_mainActionCommandToRun.Execute(null) 将触发异步操作并继续执行 CanExecute(true)。

我不能等待 Execute 因为它是一个 void 方法并且用任务包装它不会解决任何问题...

基本上,我有一个不知道它是异步方法的异步方法。

【问题讨论】:

  • 不幸的是没有 Command.ExecuteAsync() 方法......除了重新考虑你的程序逻辑以避免这种情况,或者使用 AsyncCommand (我认为 MVVM Light 有这样的命令)你可以使用锁定/信号量以同步线程/任务...
  • 我推荐使用 AsyncCommand。这是我在 NuGet 上创建的一个实现:nuget.org/packages/AsyncAwaitBestPractices.MVVM

标签: c# multithreading xamarin.forms command


【解决方案1】:

您将需要一些asynchronous command 的概念。现在一些 MVVM 库已经内置了这个:

public interface IAsyncCommand : ICommand
{
  Task ExecuteAsync(object parameter);
}

ICommand.Execute 的实现总是async void ICommand.Execute(object parameter) =&gt; await ExecuteAsync(parameter)。然后,您可以定义自己的 AsyncCommand,其工作方式与 Command 类似,只是它实现了 IAsyncCommand

然后让您的视图模型公开IAsyncCommand 而不是ICommand,您的弹出逻辑可以使用它:

private async void OnMainActionCommand(object obj)
{
  MainActionCommand.CanExecute(false);
  await _mainActionCommandToRun.ExecuteAsync(null);
  MainActionCommand.CanExecute(true);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-22
    • 2017-03-13
    • 2014-01-25
    • 2019-10-10
    • 2017-02-23
    • 1970-01-01
    相关资源
    最近更新 更多