我一直在努力掌握这个概念,即使经过多次实验,我仍然无法弄清楚WPF中的ObservableCollections和使用BindingOperations.EnableCollectionSynchronization的最佳实践。
如果我有一个带有可观察集合的viewmodel,我使用锁启用集合同步,如下所示:
m_obsverableCollection = new ObservableCollection<..>;
BindingOperations.EnableCollectionSynchronization(m_obsverableCollection,
m_obsverableCollectionLock);
这是否意味着对该可观察集合的每次修改和枚举都将:
使用BindingOperations.EnableCollectionSynchronization时,我是否需要明确地进行任何类型的锁定?
产生这一切的问题是即使在使用BindingOperations.EnableCollectionSynchronization并使用我传入该方法的相同锁定锁定项目之后,我偶尔会得到“这种类型的CollectionView不支持对其SourceCollection的更改来自与Dispatcher线程不同的线程。“ exception
答案 0 :(得分:9)
我们终于找到了它的底部:
我们必须在调度程序上启用CollectionSynchronization:
Application.Current.Dispatcher.BeginInvoke(new Action(()=>
{
BindingOperations.EnableCollectionSynchronization(m_obsverableCollection, m_observableCollectionLock);
}));
然后,每当任何其他线程想要访问observable时,您可以简单地:
lock (m_observableCollectionLock)
m_observableCollection.Add(...)
答案 1 :(得分:2)
我还没有使用过特定的语法,但每当我需要从后台线程更新ObservableCollection
时,我都会遵循以下模式:
// i just typed this off the top of my head, so be forewarned... :)
lock(someLockingObj)
{
Application.Current.Dispatcher.BeginInvoke(new Action(()=>
{
... update here....
}));
}
通常,当bg线程尝试直接更新ObservableCollection
而没有Dispatcher.BeginInvoke
(或甚至Invoke
也会工作时),您遇到的错误就会发生时代,恕我直言。。