wfp报错不支持从调度程序线程以外的线程对其 SourceCollection 进行的更改

问题

不支持从调度程序线程以外的线程对其 SourceCollection 进行的更改

出现问题的原因

该问题出现在WPF的viewmodel类中,ObservableCollection类型,该类型的 CollectionView 不支持从调度程序线程以外的线程对其 SourceCollection 进行的更改

这有点类似 C# Winform中,开启动一个新的线程(不管线程是通过什么方式开启的),要更新UI上的数据,如果直接操作,会报错,提示 线程操作不在UI线程上。

C# 这么设计是为了线程安全。

解决办法

针对C# winform程序在一个非UI线程更新UI控件 可以使用
control.InvokeRequired 来判定,当前操作是否在UI线程上。如果是在UI线程上,则直接操作。
如果不在UI线程上,则使用Control.Invoke方法调用,或者Control.BeginInvoke方法来调用。
Control.Invoke是同步方法。
Control.BeginInvoke是异步方法

  1. //同步方法调用
  2. Control.Invoke(new Action(()=>{
  3. //这里更新UI控件。就是成功的。不会有问题
  4. }));
  5. //异步方法调用
  6. Control.BeginInvoke(new Action(()=>{
  7. //这里操作UI控件,也是成功的
  8. }));

回到WPF中【不支持从调度程序线程以外的线程对其 SourceCollection 进行的更改】这个问题。
解决方法为:

  1. System.Windows.Application.Current.Dispatcher.Invoke(new Action(() => {
  2. //这里执行对 ObservableCollection 数据源的操作。就可以了
  3. }));

当然还有其他方法:参考【博客园】上的文章 WPF 不支持从调度程序线程以外的线程对其 SourceCollection 进行的更改

  1. ThreadPool.QueueUserWorkItem(delegate
  2. {
  3. SynchronizationContext.SetSynchronizationContext(new
  4. DispatcherSynchronizationContext(System.Windows.Application.Current.Dispatcher));
  5. SynchronizationContext.Current.Post(pl =>
  6. {
  7. //里面写真正的业务内容
  8. _FrameContents.Add(frame);
  9. _DataGridMain.ScrollIntoView(_FrameContents[_FrameContents.Count - 1], _DataGridMain.Columns[0]);
  10. }, null);
  11. });

至此问题解决。拜拜~~~

2024-03-22 22:00:41  user 阅读(82) 评论(0) 标签:wpf,winform,C#,跨线程操作UI控件 分类:C#