sa.*_*.he 3 c# wpf observablecollection
有几篇文章解释了 BindingOperations.EnableCollectionSynchronization 的用法。例如WPF 中的 BindingOperations.EnableCollectionSynchronization 之谜或使用 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");
}
Run Code Online (Sandbox Code Playgroud)
由于锁定,我预计调试输出如下:
task inside lock
UI thread add..
task outside lock
UI thread add..done
Run Code Online (Sandbox Code Playgroud)
但我发现这样的调试输出:
task inside lock
UI thread add..
UI thread add..done
task outside lock
Run Code Online (Sandbox Code Playgroud)
背景信息:在频繁更改的 ObservableCollection 上运行 LINQ 查询时,我偶尔会遇到 InvalidOperationExceptions“集合已修改”。这导致我将其分解为之前的示例。然后我发现我对 EnableCollectionSynchronization 工作原理的假设是错误的。
您应该使用同一锁同步对集合的所有Add访问,即您应该锁定对以下内容的调用:
lock (itemsLock)
items.Add("foo");
Run Code Online (Sandbox Code Playgroud)
文档对此非常清楚:
要在多个线程(其中之一是拥有 的 UI 线程)上使用集合
ItemsControl,应用程序具有以下职责:
EnableCollectionSynchronization以通知 WPF 该机制。| 归档时间: |
|
| 查看次数: |
1574 次 |
| 最近记录: |