问题描述
多线程模式下,同时更新同一个DataGrid (或其他控件)导致 “System.Windows.Controls.DataGrid Items.Count:n” 的生成器已接收到一个 CollectionChanged 事件序列,这些事件与 Items 集合的当前状态不符。 检测到以下差异:
累积计数 n 与实际计数 m 不相同。[累积计数的计算方式为: 上次重置时的计数 + 添加数 - 自上次重置后的删除数。
解决方案
使用系统的UI调度来添加参数:
//而且如果要执行这个Add操作,集合必须要求是 ObservableCollection<T> 类型的。
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action<MyModel>((x) =>{ YourList.Add(x); }), param);
问题分析
上述问题,对UI已绑定的集合进行Add操作需要上述操作,才能避免该问题;
但如果是直接赋值,也可避免该异常出现。可直接赋值,例如:
YourList = new List<T>();
我个人理解是控件默认的添加数据方式并不是一个安全的原子操作,需要使用同一个调度来执行方可避免计数冲突;
参考:
https://stackoverflow.com/questions/2505492/wpf-update-binding-in-a-background-thread