poc*_*oco 6 c# asynchronous mvvm async-ctp
我一直在玩新的异步CTP和MVVM模式.我一直在使用后台工作程序转换我的旧程序并报告进度以更新模型中的集合.我把它改成了这样的东西
TaskEx.Run(async () =>
{
while (true)
{
// update ObservableCollection here
}
await TaskEx.Delay(500);
});
Run Code Online (Sandbox Code Playgroud)
在我看来,我绑定到我的viewmodel,它暴露了这个可观察的集合.但是,当我的集合更新时,我得到以下异常
这种类型的CollectionView不支持从与Dispatcher线程不同的线程更改其SourceCollection.
我不确定在这样做的时候拉回到UI线程的正确方法是什么.
您不必使用异步方法Task.Run()或任何其他特殊方法来调用它们.在你的情况下,这正是导致问题的原因.
给定这样的功能:
Action f = async () =>
{
while (true)
{
// modify the observable collection here
await Task.Delay(500);
}
};
Run Code Online (Sandbox Code Playgroud)
从UI线程上运行的某个方法调用它,就像事件处理程序一样:
f();
Run Code Online (Sandbox Code Playgroud)
完全按照预期工作.它执行循环的第一次迭代,然后返回.在UI线程上500ms(或更多,如果UI线程忙)之后执行下一次迭代.
另一方面,如果你这样称呼它:
Task.Run(addNames);
Run Code Online (Sandbox Code Playgroud)
它无法正常工作.原因是async方法尝试在启动时继续处于相同的上下文中(除非您明确指定其他方式).第一个版本是在UI线程上启动的,所以它继续在UI线程上.第二个版本在ThreadPool线程上启动(感谢Task.Run())并继续在那里.这就是为什么它会导致你的错误.
所有这些都是使用SynchronizationContext,如果存在的话.