2013-11-01 62 views
7

我一直在努力去理解這個概念,即使經過很多實驗,我仍然無法弄清楚WP7中的ObservableCollections和使用BindingOperations.EnableCollectionSynchronization的最佳實踐。BindingOperations.EnableCollectionSynchronization在WPF中的神祕

如果我有一個觀察的集合視圖模型和我能夠使用鎖它集同步如下圖所示:

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

這是否意味着,每次修改,並列舉了可觀察的集合將:

  1. 使用m_obsverableCollectionLock自動鎖定集合?
  2. Marshall對創建集合的線程所做的所有修改?
  3. Marshall對綁定操作調用所在線程的所有修改?

當使用BindingOperations.EnableCollectionSynchronization時,我是否需要明確地做任何類型的鎖定?

這催生這一切,即使使用BindingOperations.EnableCollectionSynchronization並使用我傳遞到了方法相同鎖鎖定的項目後,非常偶然,我得到了「這種類型的CollectionView的不支持從改變其SourceCollection問題與分派器線程不同的線程「。例外

+0

你可以發佈代碼,你如何試圖修改集合和從哪裏?我嘗試了它在小應用程序,它完美的作品。 –

+0

問題是間歇性的,所以無法添加代碼來重現它。問題是BindingOperations.EnableSynchronization必須通過UI線程完成,否則當通過非UI線程訪問集合時可能會引發異常 – Ruskin

+0

您是在主UI線程還是從後臺線程更新ObservableCollection ?如果來自bg線程,您是否正在使用對'Application.Current.Dispatcher.BeginInvoke()'的調用進行更新?你有沒有嘗試過使用簡單的'lock()'語句(〜理智)來調用......? – code4life

回答

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也可以工作,大部分時間,恕我直言)。

+0

謝謝你,我想避免他們添加BindingOperations類,所以我們使用它來解決它...查看下面的答案:) – Ruskin

6

我們終於到它的底部:

我們必須對調度員能CollectionSynchronization:

Application.Current.Dispatcher.BeginInvoke(new Action(()=> 
{ 
    BindingOperations.EnableCollectionSynchronization(m_obsverableCollection, m_observableCollectionLock); 
})); 

然後每次任何其他線程想要訪問觀察到的,你可以簡單地說:

lock (m_observableCollectionLock) 
    m_observableCollection.Add(...)