WPF ObservableCollection 异步调用问题
问题介绍
当ObservableCollection列表被UI线程占用时,如果在异步线程中调用ObservableCollection,会弹出以下异常:

问题分析
我们使用一个viewModel,在ViewModel中添加ObservableCollection类型的ItemsSource列表。
在列表使用ListBox绑定ItemsSource列表。再由界面触发对ItemsSource的修改。
public class ViewModel : INotifyPropertyChanged
{
private ObservableCollection<string> _itemsSource = new ObservableCollection<string>(); public ObservableCollection<string> ItemsSource
{
get => _itemsSource;
set
{
_itemsSource = value;
OnPropertyChanged();
}
} public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
1. 直接在异步线程下修改ObservableCollection--报错
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
var viewModel = this.DataContext as ViewModel;
Task.Run(() =>
{
//此段调用异常
viewModel.ItemsSource.Add("test1");
});
}
2. 在异步线程下,赋值ObservableCollection--正常
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
var viewModel = this.DataContext as ViewModel;
Task.Run(() =>
{
//此段不会报错
var list = viewModel.ItemsSource.ToList();
list.Add("test0");
viewModel.ItemsSource = new ObservableCollection<string>(list);
});
}
3. 在异步线程下,赋值ObservableCollection后,再修改ObservableCollection--正常
private void Button1_OnClick(object sender, RoutedEventArgs e)
{
var viewModel = this.DataContext as ViewModel;
Task.Run(() =>
{
//此段不会报错
viewModel.ItemsSource = new ObservableCollection<string>(new List<string>() { "test3", "test2" });
//此段不会报错
viewModel.ItemsSource.Add("test4");
});
}
在异步线程下设置的ItemsSource,可以被当前异步线程调用。
4. 异步线程下赋值ObservableCollection,然后在UI线程修改ObservableCollection--正常
private void Button1_OnClick(object sender, RoutedEventArgs e)
{
var viewModel = this.DataContext as ViewModel;
Task.Run(() =>
{
//此段不会报错
viewModel.ItemsSource = new ObservableCollection<string>(new List<string>() { "test0" });
});
} private void Button2_OnClick(object sender, RoutedEventArgs e)
{
var viewModel = this.DataContext as ViewModel;
//此段不会报错
viewModel.ItemsSource.Add("test2");
}
在异步线程下设置的ItemsSource,可以被UI线程调用。此处可以理解为,赋值时,框架默默转到UI线程处理了?
但是上面3流程,为何正常,so weird~
5. 异步线程下,回到UI线程中,修改ObservableCollection--正常
private void Button1_OnClick(object sender, RoutedEventArgs e)
{
var viewModel = this.DataContext as ViewModel;
Task.Run(() =>
{
Application.Current.Dispatcher.Invoke(() =>
{
//此段不会报错
viewModel.ItemsSource.Add("test");
});
});
}
WPF ObservableCollection 异步调用问题的更多相关文章
- WPf ObservableCollection异步调用问题
当ObservableCollection列表被UI线程占用时,如果在异步线程中调用ObservableCollection,会弹出以下异常: private void Button1_OnClick ...
- Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务、WCF消息头添加安全验证Token
原文:Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务.WCF消息头添加安全验证Token 为什么选择wcf? 因为好像wcf和wpf就是哥俩,,, 为什么选择异步 ...
- 【ASP.NET Web API教程】3.3 通过WPF应用程序调用Web API(C#)
原文:[ASP.NET Web API教程]3.3 通过WPF应用程序调用Web API(C#) 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的 ...
- 如何实现异步调用WCF
在面向服务的.NET开发中,我们经常要调用WCF服务加载数据,这时候,如果使用同步调用,会阻止UI,影响用户体验UE/UX,而且当服务器ping不通或者网速特别烂的情况下,这时候基本上是处于卡死状态, ...
- Windows 8 应用开发 - 异步调用
原文:Windows 8 应用开发 - 异步调用 不论是桌面客户端还是Web应用通常会出现处理时间较长的操作,为了在这段时间内不影响用户与应用之间的交互体验,开发人员通常会使用异步调用技术,使 ...
- silverlight——多次异步调用的顺序执行
遇到这样一个功能需求,对于后台的同一个服务调用多次,但要求传入的参数能够再一个执行完之后再进行另一个参数的执行. 由于silverlight支持的是异步调用机制,故无法控制服务调用何时返回.那么如果使 ...
- C#委托异步调用
参考页面: http://www.yuanjiaocheng.net/webapi/mvc-consume-webapi-get.html http://www.yuanjiaocheng.net/w ...
- Direct3D Draw函数 异步调用原理解析
概述 在D3D10中,一个基本的渲染流程可分为以下步骤: 清理帧缓存: 执行若干次的绘制: 通过Device API创建所需Buffer: 通过Map/Unmap填充数据到Buffer中: 将Buff ...
- 一个简单的webservice的demo(下)winform异步调用webservice
绕了一大圈,又开始接触winform的项目来了,虽然很小吧.写一个winform的异步调用webservice的demo,还是简单的. 一个简单的Webservice的demo,简单模拟服务 一个简单 ...
随机推荐
- Java中ArrayList学习笔记
1. 先看两段代码 这段代码在执行的时候会报 但是这样写就好着呢: 总结,研究报错的代码 ,在for循环的时候调用next()方法,next方法中调用了checkForComodification这个 ...
- SSL,TLS
今天突然收到邮件说SSL不能用了,基于SSL的HTTPS协议不通了,怎么办? java/android 的网络编程简直一窍不通,平时都是用到了问百度.只能恶补有关网络的知识了. 传输协议: 传输协议中 ...
- 学习CSS3之实心圆
CSS3是最新版本的CSS,学习后可以更好的用于工作及自己修改自己代码的各种样式. border-radius圆角方法画实心圆.相当于在长方形(正方形)上画半径为边长一半的圆弧. 效果如上图,代码如下 ...
- 阿里云卸载自带的JDK,安装JDK完成相关配置
0.预备工作 笔者的云服务器购买的是阿里云的轻量应用服务器,相比于云服务器ECS,轻量应用服务器是固定流量但是网络带宽较高,对于服务器来说,网络带宽是非常昂贵的,而带宽也决定了你的应用访问的流畅度,带 ...
- 《k8s-1.13版本源码分析》-调度优选
源码分析系列文章已经开源到github,地址如下: github:https://github.com/farmer-hutao/k8s-source-code-analysis gitbook:ht ...
- Spring boot打包war包
1.设置打包的类型(war/jar) 在pom.xml里设置 <packaging>war</packaging> 2.移除嵌入式tomcat插件 //在pom.xml里找到s ...
- 泛微关于js设计的一些小技巧
1.关于泛微流程的js设计 泛微oa可以插入javascript可以diy自己想要的表单页面前端功能.如果有前端开发经验,或者熟练使用jQuery的话,这将变得非常容易!同时泛微OA内部有很多库,包括 ...
- Spring之AOP详解
文章大纲 一.AOP介绍二.Spring的AOP实战三.AOP常用标签四.项目源码及参考资料下载五.参考文章 一.AOP介绍 1. 什么是AOP 在软件业,AOP为Aspect Oriented ...
- 当心Azure跨区域数据传输产生额外费用
最近同事发现Azure上一台虚拟机的费用环比增加了一部分.后面仔细检查发现费用来自数据传输, 因为这是早期部署的一台Azure虚拟机(Iaas),我们在本地生成备份,然后通过AzCopy到存储账号的B ...
- cmd实现cab文件的压缩与解压
压缩(makecab): 1.单文件压缩 makecab ip2.txt ip2.txt.cab 2.多文件压缩 makecab /f c:\list.txt /d expresstype=mszip ...