有这样一个场景,在vm中,我们为了ui的体验,会异步访问后端接口,获取数据集合,如果这个集合绑定到界面,并且在线程内,怎么处理?
有人讲:this.Dispatcher.Invoke,如果在vm内呢? 有人讲:Application.Current.Dispatcher.Invoke
每个集合都包起来?不太舒爽吧。。
这里有个更好的方案介绍给大家,就是SynchronizationContext,同步上下文。
基于WPF的ObservableCollection扩展
public class AsyncObservableCollection<T> : ObservableCollection<T> { private SynchronizationContext _synchronizationContext = SynchronizationContext.Current; public AsyncObservableCollection() { } public AsyncObservableCollection(IEnumerable<T> list) : base(list) { } protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { if (SynchronizationContext.Current == _synchronizationContext) { RaiseCollectionChanged(e); } else { _synchronizationContext.Post(RaiseCollectionChanged, e); } } private void RaiseCollectionChanged(object param) { base.OnCollectionChanged((NotifyCollectionChangedEventArgs)param); } protected override void OnPropertyChanged(PropertyChangedEventArgs e) { if (SynchronizationContext.Current == _synchronizationContext) { RaisePropertyChanged(e); } else { _synchronizationContext.Post(RaisePropertyChanged, e); } } private void RaisePropertyChanged(object param) { base.OnPropertyChanged((PropertyChangedEventArgs)param); } }
在第一次实例话的时候去记录当前线程上下文,下次不是同一个线程的时候,将集合同步到ui线程处理。
欢迎有其他方案的小伙伴共同交流,页面下方可以加入我们。