在WPF 4.5中跨线程更新集合
WPF中一个非常强大的功能是数据绑定,我们可以把一个集合绑定到ListBox中,当集合的数据发生变更时,ListBox界面也会同步变更。本身这是一个非常美好的事情,但是美中不足的是:当把集合绑定到ListBox中的时候,集合也顺带继承了ListBox的这种不能夸线程访问的限制。例如,如下代码就会抛出跨线程访问异常。

解决这个问题的一个传统方式是把对集合的修改Post到UI线程中来,改成如下形式。
ThreadPool.QueueUserWorkItem(async _ =>
{
await
Task.Delay(1000);
this.Dispatcher.Invoke(new
Action(()=>collection.Add(DateTime.Now.ToString())), null);
});
不过这种写法显得很繁琐,在.Net 4.5提供了新的一种线程安全访问机制,那就是用BindingOperations.EnableCollectionSynchronization使能集合同步:
var collection = new
ObservableCollection<string>();
listBox.ItemsSource = collection;
var lockObj = new
object();
BindingOperations.EnableCollectionSynchronization(collection, lockObj);
ThreadPool.QueueUserWorkItem(async _ =>
{
await
Task.Delay(1000);
collection.Add(DateTime.Now.ToString());
});
这样,对集合访问就没有UI线程限制了,要方便不少。没有细研究其内部实现机制,貌似是通过加锁实现的。
与之相对的是,还提供了一个去使能集合同步的函数BindingOperations.DisableCollectionSynchronization。网上的文章说是使用完后要用这个函数去使能集合同步,否则会以为集合的引用没有释放导致内存泄漏。不过,我自己写代码试了一下,即使不用它解除锁定,集合对象还是能正常释放的,应该保存的只是一个弱引用,不主动解除锁定也没有内存泄漏问题。
在WPF 4.5中跨线程更新集合的更多相关文章
- WPF Dispatcher.BeginInvoke子线程更新UI
在开发WPF应用时出现:”调用线程无法访问此对象,因为另一个线程拥有该对象.“ 是因为UI线程是WPF应用的主线程,若尝试子线程更新UI线程应使用Dispatcher.BeginInvoke()或者I ...
- WPF 非UI线程更新UI界面的各种方法小结
转载:https://www.cnblogs.com/bdbw2012/articles/3777594.html 我们知道只有UI线程才能更新UI界面,其他线程访问UI控件被认为是非法的.但是我们在 ...
- .NET一个线程更新另一个线程的UI(两种实现方法及若干简化)
Winform中的控件是绑定到特定的线程的(一般是主线程),这意味着从另一个线程更新主线程的控件不能直接调用该控件的成员. 控件绑定到特定的线程这个概念如下: 为了从另一个线程更新主线程的Window ...
- 编写高质量代码改善C#程序的157个建议——建议87:区分WPF和WinForm的线程模型
建议87:区分WPF和WinForm的线程模型 WPF和WinForm窗体应用程序都有一个要求,那就是UI元素(如Button.TextBox等)必须由创建它的那个线程进行更新.WinForm在这方面 ...
- Winform非UI线程更新UI界面的各种方法小结
我们知道只有UI线程才能更新UI界面,其他线程访问UI控件被认为是非法的.但是我们在进行异步操作时,经常需要将异步执行的进度报告给用户,让用户知道任务的进度,不至于让用户误认为程序“死掉了”,特别是对 ...
- C# 跨线程更新 UI
Winforms 跨线程更新 UI 在 Winforms 中, 所有的控件都包含 InvokeRequired 属性, 如果我们要更新UI,通过它我们可以判断是否需要调用 [Begin]Invoke. ...
- 非UI线程更新UI界面的各种方法小结
转载:https://www.cnblogs.com/xiashengwang/archive/2012/08/18/2645541.html 我们知道只有UI线程才能更新UI界面,其他线程访问UI控 ...
- C#的变迁史 - C# 4.0 之线程安全集合篇
作为多线程和并行计算不得不考虑的问题就是临界资源的访问问题,解决临界资源的访问通常是加锁或者是使用信号量,这个大家应该很熟悉了. 而集合作为一种重要的临界资源,通用性更广,为了让大家更安全的使用它们, ...
- 学习通过Thread+Handler实现非UI线程更新UI组件
[Android线程机制] 出于性能考虑,Android的UI操作并不是线程安全的,这就意味着如果有多个线程并发操作UI组件,可能导致线程安全问题.为了解决这个问题,Android制定了一条简单的规则 ...
随机推荐
- 动态规划&字符串:最长公共子串
还是直接上转移方程: 动规只能解决O(n^2)的最长公共子串问题 使用后缀数组或者SAM可以高效地解决这个问题 所以,对于这个问题,动规的代码就不给出了 直接给出SAM的实现,也为以后学习SAM打下一 ...
- Nodejs写的搬家工具知识分享
这篇文章 主要学习这两个模块的使用: request-promise-native : https://github.com/request/request-promise-native cheeri ...
- linux下检测可用串口并使用minicom打开
目前使用minicom作为串口软件.但使用过程中,有一点感觉不方便的地方,就是我需要使用多个串口,当使用的不是串口0时,就要手动修改minicom的配置. 于是考虑实现脚本,自动列出当前串口,选择后调 ...
- Linux环境下通过ODBC访问MSSql Server
为了解决Linux系统连接MSSql Server的问题,微软为Linux系统提供了连接MSSql Server的ODBC官方驱动.通过官方驱动,Linux程序可以方便地对MSSql Server进行 ...
- [NOIP 2010] 引水入城
搜索+贪心. 参考博客:http://blog.sina.com.cn/s/blog_8442ec3b0100xib1.html 主要是要看出来,如果有解的话,每个沿湖城市能够流到的范围是连续的区间. ...
- Python实现图片转字符画
from PIL import Image def get_char(r, g, b, alpha=256): ascii_char = '''$@B%8&WM#*oahkbdpqwmZO0Q ...
- 对象存储 - Swift 原理 及 Swift+keystone+dashboard 架构搭建
1. 原理介绍 Swift 架构.原理及功能: http://www.cnblogs.com/sammyliu/p/4955241.html 总结的很详细也很全面,受益匪浅,感谢分享. 2. keys ...
- css的class, id等常用命名规则
CSS的class.id.css文件名的常用命名规则 (一)常用的CSS命名规则 头:header 内容:content/container 尾:footer 导航:nav 侧栏:sid ...
- 【计算机网络】http中get和post的区别
常见回答: 1. GET使用URL或Cookie传参.而POST将数据放在BODY中. 2. GET的URL会有长度上的限制,则POST的数据则可以非常大. 3. POST比GET安全,因为数据在地址 ...
- flask学习:如何从config里载入配置
代码如下: 1.main.py from flask import Flask from config import DevConfig app=Flask(__name__) app.config. ...