gpt4 book ai didi

c# - 为什么 CollectionChanged 不是线程安全的?

转载 作者:行者123 更新时间:2023-12-03 12:49:16 26 4
gpt4 key购买 nike

我正在开发一个 WPF 应用程序,发现绑定(bind)属性的属性更改通知可以从后台线程发生,但是要对 observablecollection 进行任何更改(如添加或删除项目)必须从 UI 线程发生。我的问题是为什么会这样? INotifyPropertyChanged 和 INotifyCollectionChanged 都是由 UI 控件订阅的,那么为什么 INotifyPropertyChanged 会出现异常?

例如:

 public class ViewModel : INotifyPropertyChanged
{
ObservableCollection<Item> _items = new ObservableCollection<Item>();

private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
//Can fire this from a background thread without any crash and my
//Name gets updated in the UI
InvokePropertyChanged(new PropertyChangedEventArgs("Name"));
}
}

public void Add(Item item)
{
//Cant do this from a background thread and has to marshal.
_items.Add(item);
}

public event PropertyChangedEventHandler PropertyChanged;

public void InvokePropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, e);
}
}

注意:来自后台线程的 CollectionChanged 事件会使应用程序崩溃,但是来自后台线程的 PropertyChanged 事件更新 UI 没有任何问题,是的,这是在 .NET 4.0 中

最佳答案

这个问题与线程安全无关。问题是 CollectionChanged 事件是从工作线程引发的,这意味着处理程序是在同一线程中执行的,当处理程序试图触摸 UI 时,您会遇到异常,因为这只允许来自UI 线程。

如果情况相同,PropertyChanged 事件也会发生同样的情况,没有对这两个事件给予特殊处理。

如果您需要从事件处理程序中触摸 UI,那么您必须确保 the event is raised on the UI thread否则,事件处理程序必须使用 Dispatcher.CheckAccess 检查是否需要对 UI 线程进行编码更改,并使用 Dispatcher.BeginInvoke 来执行此操作。

关于c# - 为什么 CollectionChanged 不是线程安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19183841/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com