【发布时间】: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