Есть несколько постов, в которых объясняется использование BindingOperations.EnableCollectionSynchronization. Например. BindingOperations.EnableCollectionSynchronization mystery in WPF или Использование BindingOperations.EnableCollectionSynchronization
Однако моё понимание «блокировки» не соответствует поведению следующей демонстрации.
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");
}
Из-за блокировки я ожидал отладочный вывод, подобный этому:
task inside lock
UI thread add..
task outside lock
UI thread add..done
Но я нахожу вывод отладки примерно так:
task inside lock
UI thread add..
UI thread add..done
task outside lock
Справочная информация: я иногда испытываю InvalidOperationExpetions «коллекция была изменена» при выполнении запросов LINQ для часто изменяемой ObservableCollection. Это привело меня к разрушению предыдущего примера. Тогда я обнаружил, что мое предположение о том, как работает EnableCollectionSynchronization, неверно.