等待Command.Execute进行或不执行异步操作

时间:2019-02-27 13:34:54

标签: c# multithreading xamarin.forms command

我碰到一个奇怪的案件,被卡在上面。

我有一个Popup View + ViewModel,它是其中的一个按钮。弹出窗口从其他视图获取命令以执行按钮。

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

这就是我现在拥有的:

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方法,用任务包装它不会解决任何问题...

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

1 个答案:

答案 0 :(得分:0)

您将需要一些asynchronous command的概念。如今,某些MVVM库具有内置功能:

std::unique

其中public interface IAsyncCommand : ICommand { Task ExecuteAsync(object parameter); } 实现始终为ICommand.Execute。然后,您可以定义自己的async void ICommand.Execute(object parameter) => await ExecuteAsync(parameter),其作用类似于AsyncCommand,但它实现了Command

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

ICommand
相关问题