WPF中的BindingOperations.EnableCollectionSynchronization之谜

时间:2013-11-01 20:22:24

标签: c# .net wpf

我一直在努力掌握这个概念,即使经过多次实验,我仍然无法弄清楚WPF中的ObservableCollections和使用BindingOperations.EnableCollectionSynchronization的最佳实践。

如果我有一个带有可观察集合的viewmodel,我使用锁启用集合同步,如下所示:

m_obsverableCollection = new ObservableCollection<..>;
BindingOperations.EnableCollectionSynchronization(m_obsverableCollection,
                                                   m_obsverableCollectionLock);

这是否意味着对该可观察集合的每次修改和枚举都将:

  1. 使用m_obsverableCollectionLock自动锁定集合?
  2. Marshall对创建集合的线程进行了所有修改?
  3. Marshall对进行绑定操作的线程进行了所有修改吗?
  4. 使用BindingOperations.EnableCollectionSynchronization时,我是否需要明确地进行任何类型的锁定?

    产生这一切的问题是即使在使用BindingOperations.EnableCollectionSynchronization并使用我传入该方法的相同锁定锁定项目之后,我偶尔会得到“这种类型的CollectionView不支持对其SourceCollection的更改来自与Dispatcher线程不同的线程。“ exception

2 个答案:

答案 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也会工作时),您遇到的错误就会发生时代,恕我直言。。