making observablecollection thread safe
//as a field in class where OC is instantiated:
using System.Collections.ObjectModel; //for ObservableCollection<T>
using System.Windows.Data; //for BindingOperations
using System.Windows; //for Application
using System.Threading; //for Dispatcher
public static object m_lockObject; //NOTE: One lockObject per collection!
public static ObservableCollection<T> m_OC;
//where OC is created (typically the constructor)
OC = new ObservableCollection<T>();
BindingOperations.EnableCollectionSynchronization(m_OC, m_lockObject);
Application.Current.Dispatcher.Send(
DispatcherPriority.Background,
new Action(() => {
BindingOperations.EnableCollectionSynchronization(m_OC, m_lockObject);
}));
//the call of EnableCollectionSynchronization MUST happen on the UI thread.
//This Dispatcher action ensures that it does.
//-- FINALLY --
//when altering OC will trigger OnPropertyChanged (.Add(), .Clear(), etc.)
//encase such statements within a lock using that OC's lockObject
lock (m_lockObject)
{
m_OC.Add(null);
}
//ALTERNATE SOLUTION: do any alterations to the OC on the Dispatcher thread
Application.Current?.Dispatcher?.Invoke(() =>
{
//Do stuff
});