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