2013-11-01 8 views
7

'da senkronizasyon gizemi Bu konsepti kavramak için uğraşıyordum ve birçok deneyden sonra bile WPF'deki ObservableCollections ile en iyi uygulamanın ne olduğunu ve BindingOperations.EnableCollectionSynchronization'ı kullanarak ne olduğunu anlayamıyorum.BindingOperations.EnableCollection WPF

Bir gözlemlenebilir koleksiyonu ile ViewModel sahip ve aşağıda gösterildiği gibi Benim kilidi kullanarak Üzerinde toplama senkronizasyonu etkinleştirirseniz:

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

anlamına mı geliyor gözlemlenebilir koleksiyonu üzerinde her modifikasyon ve numaralandırma eder:

  1. Koleksiyonu m_obsverableCollectionLock kullanarak otomatik olarak kilitleyin.
  2. Marshall, koleksiyonun oluşturulduğu iş parçasındaki tüm değişiklikleri mi?
  3. Marshall bağlama işlemlerinin yapıldığı iş parçacığındaki tüm değişiklikler yapıldı mı?

BindingOperations.EnableCollectionSynchronization kullanırken, hiç bir şekilde açıkça kilitleme yapmam gerekecek mi?

Tüm bunlar, BindingOperations.EnableCollectionSynchronization ve kilitleme öğelerini kullandıktan sonra bile bu yönteme geçtiğinde bile, bu arada, aldığım "Bu CollectionView türünün SourceCollection öğesindeki değişiklikleri desteklememesidir. Dispatcher dizisinden farklı bir konu. " istisna

+0

Toplamayı nasıl düzenlediğinizi ve nereden aldığınızı yazabilir misiniz? Küçük uygulamada denedim ve mükemmel bir şekilde çalışıyor. –

+0

Sorun aralıklıydı, bu nedenle yeniden üretmek için kod ekleyemedi. Sorun, BindingOperations.EnableSynchronization UI iş parçacığı aracılığıyla yapılması gerekiyordu, aksi halde koleksiyon UI olmayan iş parçacığı aracılığıyla erişilen bir özel durum olasılığını var oldu – Ruskin

+0

Ana UI iş parçacığı üzerinde ObservableCollection veya arka plan iş parçacığı güncelleştiriliyor musunuz ? Bg iş parçacığından, bu güncelleştirmeyi "Application.Current.Dispatcher.BeginInvoke()') kullanarak yapıyor musunuz? Bu çağrıyı basit bir 'lock()' ifadesi (~ aklı) kullanarak ... denediniz mi? – code4life

cevap

2
Ben özellikle sözdizimi, ancak bir arka plan iş parçacığı bir ObservableCollection güncellemek gerektiğinde, ben bu modeli takip kullanmadıysanız

:

// i just typed this off the top of my head, so be forewarned... :) 
lock(someLockingObj) 
{ 
    Application.Current.Dispatcher.BeginInvoke(new Action(()=> 
    { 
     ... update here.... 
    })); 
} 

Genellikle Karşılaştığınız hata oluşur Bir bg iş parçacığı, ObservableCollection doğrudan, Dispatcher.BeginInvoke (veya Invoke, çoğu zaman, IMHO da çalışırdı) güncelleştirmeye çalışıyor.

Biz memuru üzerinde CollectionSynchronization etkinleştirmek zorunda:

+0

Bunun için, BindingOperations sınıfını eklediklerinden kaçınmayı düşünüyorum, bu yüzden bunu kullanarak çözdük ... aşağıya bakın :) – Ruskin

6

Sonunda bunun altına aldık

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

Sonra her herhangi bir başka iplik gözlemlenebilir erişmek isteyen sadece can:

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