【发布时间】:2020-06-18 17:42:53
【问题描述】:
XAML 绑定到一个 ViewModel MainVM,它加载了另外两个子 ViewModel SubVM1 和 SubVM2。我正在使用asynchronous command presented by John Thiriet。我的意图:使用 MainVM 中定义的命令,使用来自 SubVM1 的异步函数来更新来自 SubVM2 的属性。
(XAML)
<Window.Resources>
<local:MainVM x:Key="main"/>
<local:SubVM2 x:Key="subvm2"/>
</Window.Resources>
<Grid>
<Label Content="{Binding MyValue}" DataContext="{StaticResource subvm2}" FontSize="40"/>
<Button Command="{Binding MyCommand}" DataContext="{StaticResource main}" Width="100" Height="100" Content="GO"/>
</Grid>
主虚拟机
class MainVM : VMBase
{
private SubVM1 _subvm1;
private SubVM2 _subvm2;
private bool _isBusy;
public SubVM1 Subvm1
{
get => _subvm1;
set
{ _subvm1 = value; OnPropertyChanged("Subvm1"); }
}
public SubVM2 Subvm2
{
get => _subvm2;
set
{ _subvm2 = value; OnPropertyChanged("Subvm2"); }
}
public bool IsBusy
{
get => _isBusy;
set
{ _isBusy = value; OnPropertyChanged("IsBusy"); }
}
public IAsyncCommand MyCommand { get; set; }
public MainVM()
{
Subvm1 = new SubVM1();
Subvm2 = new SubVM2();
MyCommand = new AsyncCommand(Increment, MuchBusiness);
}
private async Task Increment()
{
try
{
IsBusy = true;
await Subvm1.MyAsyncFunc(Subvm2.MyValue);
}
finally
{
IsBusy = false;
}
}
private bool MuchBusiness()
{
return !IsBusy;
}
}
子虚拟机1
class SubVM1 : VMBase
{
public async Task MyAsyncFunc(double MyValue)
{
await Task.Run(() =>
{
int i = 0;
while (i < 20)
{
MyValue = i;
i++;
Console.WriteLine(MyValue);
}
});
}
}
子虚拟机2
class SubVM2 : VMBase
{
private double _myValue;
public double MyValue
{
get => _myValue;
set
{ _myValue = value; OnPropertyChanged("MyValue"); }
}
public SubVM2() { }
}
我尝试使用this article from Stephen Cleary。这真的很有启发性,但我只知道我做错了。我似乎无法弄清楚如何使用他提供的代码。另外,我找不到通常真正帮助我理解的源代码。
我也读过dispatchers,但同样,没有源代码
有 this solution 旨在修改 OnPropertyChanged,但这是来自 win8 应用程序,我无法从那里推断。
【问题讨论】:
-
请注意,除了调用
await Task.Run()之外什么都不做的public async Task方法不应该是异步的:public Task MyAsyncFunc(double MyValue) { return Task.Run(() => { ... }); } -
@Clemens 即使我不想退货?在“真实”代码中,此 Async 函数运行一个负载平台,我希望在单独的线程上处理该操作。
-
await MyAsyncFunc()已经在等待任务了。 -
哦,是的,对不起,昨天读到这里很累。在 await Task.Run 前后确实有一堆 UI 相关的更新。
标签: c# wpf asynchronous mvvm