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,简单模拟服务 一个简单 ...
随机推荐
- Appium+python的环境搭建!
我的电脑64位操作系统 下载并安装所需软件: 1.adb环境 2.下载(python-2.7.12.amd64.msi)并安装python 3.下载并解压adt,如(adt-bundle-window ...
- 深入浅出java常量池
理论 jvm虚拟内存分布: 程序计数器是jvm执行程序的流水线,存放一些跳转指令. 本地方法栈是jvm调用操作系统方法所使用的栈. 虚拟机栈是jvm执行java代码所使用 ...
- Java转Ruby【快速入门】
最近参加实习了,公司的技术栈中需要用到 Ruby 以及 Rails 框架,所以算是开始了踩坑之旅吧.. Ruby 简介 网上的简介要搜都能搜到,具体涉及的包括历史啦之类这里不再赘述,提几个关键词吧: ...
- 434个H5游戏源码
各种类型HTML5游戏,界面和JS均可供项目参考 下面是下载地址
- 为什么面试你要25K,HR只给你20K?
周末了,我们来聊个轻松的话题,关于涨薪,哈哈~ 前阵子,栈长给大家分享了<为什么公司宁愿 25K 重新招人,也不给你加到 20K?>,今天我们来聊一个差不多的话题: 为什么面试你要25K, ...
- javascript深入理解-从作用域链理解闭包
一.概要 红宝书(P178)对于闭包的定义:闭包就是有权访问另外一个函数作用域中变量的函数. MDN,对于闭包的定义:闭包就是指能够访问自由变量的函数. 那么什么是自由变量?自由变量就是在函数中使用, ...
- 开发小白也毫无压力的hexo静态博客建站全攻略 - 躺坑后亲诉心路历程
目录 基本原理 方法1 - 本机Windows下建站 (力荐) 下载安装node.js 用管理员权限打开命令行,安装hexo-cli和hexo 下载安装git 初始化hexo 使用hexo gener ...
- Python进阶:设计模式之迭代器模式
在软件开发领域中,人们经常会用到这一个概念——“设计模式”(design pattern),它是一种针对软件设计的共性问题而提出的解决方案.在一本圣经级的书籍<设计模式:可复用面向对象软件的基础 ...
- Oracle 分页查询与数据去重
1.rownum字段 Oracle下select语句每个结果集中都有一个伪字段(伪列)rownum存在.rownum用来标识每条记录的行号,行号从1开始,每次递增1.rownum是虚拟的顺序值,前提是 ...
- 用系统为centos6的主机,搭建PXE服务器,实现批量安装centos6,7系统
1. iptables -F setenforce 0 临时关掉selinux,清掉防火墙 永久生效更改配置文件:vim /etc/sysconfig/selinux chkconfig iptabl ...