There are several posts that explain the usage of BindingOperations.EnableCollectionSynchronization. E.g. BindingOperations.EnableCollectionSynchronization mystery in WPF or Using BindingOperations.EnableCollectionSynchronization
However, my understanding of a "lock" does not match the behavior of the following demonstration.
private void Button_Click(object sender, RoutedEventArgs e)
{
var itemsLock = new object();
var items = new ObservableCollection<string>();
BindingOperations.EnableCollectionSynchronization(items, itemsLock);
Task.Run(() =>
{
lock (itemsLock)
{
Debug.WriteLine("task inside lock");
Thread.Sleep(5000);
items.Where(m => m == "foo").ToArray();
}
Debug.WriteLine("task outside lock");
});
Thread.Sleep(1000);
Debug.WriteLine("UI thread add..");
items.Add("foo");
Debug.WriteLine("UI thread add..done");
}
Due to the lock, I expected Debug Output like this:
task inside lock
UI thread add..
task outside lock
UI thread add..done
But I find an Debug Output like this:
task inside lock
UI thread add..
UI thread add..done
task outside lock
Background info: I occasionally experience InvalidOperationExceptions "collection was modified" when running LINQ queries on a frequently changed ObservableCollection. This lead me to breaking it down to the previous sample. Then I found that my assumption of how EnableCollectionSynchronization works is wrong.