WPF 绑定到并发集合安全吗?
Is WPF binding to concurrent collections safe?
我想知道,将 WPF 控件绑定到并发集合是否安全,特别是围绕还实现了 INotifyCollectionChanged
的 System.Collections.Concurrent
集合之一的包装器 class?
我知道 CollectionChanged
必须在 UI 线程上调用(并且没有索引参数)。但是,如果另一个线程在 UI 更新自身时操作源集合,会发生什么? WPF 是否只是优雅地忽略了这个问题(就像它在许多其他地方所做的那样)?
这取决于包装器的实现。让我们做一个简单的例子,将 INotifyCollectionChanged
添加到 BlockingCollection<T>
允许调用非 UI 线程:
public void AddNotified(T item)
{
base.Add(item);
var args = new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add,
item,
Count - 1);
//Ensure no items are changed until the UI is updated
Application.Current.Dispatcher.Invoke(() =>
CollectionChanged?.Invoke(this, args));
}
Add
的实现本身是线程安全的,但要确保 UI 显示当前项目,您需要确保在添加和更新之间没有更改其他项目的实现(请参阅代码中的注释)。
WPF 基于 NotifyCollectionChangedAction
and updated items passed at raising the INotifyCollectionChanged.CollectionChanged
更新 UI。这意味着 UI 依赖于此信息。结果:临时集合更新导致不同步 UI,直到引发更新或调用 NotifyCollectionChangedAction.Reset
并且 UI 显示不同的项目,例如源集合中的项目。
将集合与 UI 同步是一个非常广泛且有趣的话题。已经有多种解决方案可以满足您的特定问题。为您提供一些可能的方法来解决此类问题,请查看以下链接:
- Is there a Threadsafe Observable collection in .NET 4?
- Threadsafe ObservableCollection
BindingOperations.EnableCollectionSynchronization
我想知道,将 WPF 控件绑定到并发集合是否安全,特别是围绕还实现了 INotifyCollectionChanged
的 System.Collections.Concurrent
集合之一的包装器 class?
我知道 CollectionChanged
必须在 UI 线程上调用(并且没有索引参数)。但是,如果另一个线程在 UI 更新自身时操作源集合,会发生什么? WPF 是否只是优雅地忽略了这个问题(就像它在许多其他地方所做的那样)?
这取决于包装器的实现。让我们做一个简单的例子,将 INotifyCollectionChanged
添加到 BlockingCollection<T>
允许调用非 UI 线程:
public void AddNotified(T item)
{
base.Add(item);
var args = new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add,
item,
Count - 1);
//Ensure no items are changed until the UI is updated
Application.Current.Dispatcher.Invoke(() =>
CollectionChanged?.Invoke(this, args));
}
Add
的实现本身是线程安全的,但要确保 UI 显示当前项目,您需要确保在添加和更新之间没有更改其他项目的实现(请参阅代码中的注释)。
WPF 基于 NotifyCollectionChangedAction
and updated items passed at raising the INotifyCollectionChanged.CollectionChanged
更新 UI。这意味着 UI 依赖于此信息。结果:临时集合更新导致不同步 UI,直到引发更新或调用 NotifyCollectionChangedAction.Reset
并且 UI 显示不同的项目,例如源集合中的项目。
将集合与 UI 同步是一个非常广泛且有趣的话题。已经有多种解决方案可以满足您的特定问题。为您提供一些可能的方法来解决此类问题,请查看以下链接:
- Is there a Threadsafe Observable collection in .NET 4?
- Threadsafe ObservableCollection
BindingOperations.EnableCollectionSynchronization