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。网上的文章说是使用完后要用这个函数去使能集合同步,否则会以为集合的引用没有释放导致内存泄漏。不过,我自己写代码试了一下,即使不用它解除锁定,集合对象还是能正常释放的,应该保存的只是一个弱引用,不主动解除锁定也没有内存泄漏问题。

转载于:https://www.cnblogs.com/TianFang/p/3481282.html

在WPF 4.5中跨线程更新集合相关推荐

  1. 同步上下文(SynchronizationContext) 和 C#中跨线程更新UI的方法总结

    同步上下文(SynchronizationContext) 和 C#中跨线程更新UI的方法总结 在C#编程环境中,不允许在工作线程中直接对主线程(UI线程)中的控件进行更新操作.因此,稍微复杂一点的程 ...

  2. Java学习day096 并发(六)(线程安全的集合:高效的映射、集和队列、映射条目的原子更新、对并发散列映射的批操作、并发集视图、写数组的拷贝、并行数组算法、较早的线程安全集合)

    使用的教材是java核心技术卷1,我将跟着这本书的章节同时配合视频资源来进行学习基础java知识. day096   并发(六)(线程安全的集合:高效的映射.集和队列.映射条目的原子更新.对并发散列映 ...

  3. 如何从另一个线程更新GUI?

    从另一个线程更新Label的最简单方法是什么? 我在thread1上有一个Form , thread1开始,我开始了另一个线程( thread2 ). 当thread2处理某些文件时,我想使用thre ...

  4. .NET一个线程更新另一个线程的UI(两种实现方法及若干简化)

    本片博文接上一篇:.NET多线程执行函数,给出实现一个线程更新另一个线程UI的两种方法. Winform中的控件是绑定到特定的线程的(一般是主线程),这意味着从另一个线程更新主线程的控件不能直接调用该 ...

  5. 编写高质量代码改善C#程序的157个建议——建议87:区分WPF和WinForm的线程模型...

    建议87:区分WPF和WinForm的线程模型 WPF和WinForm窗体应用程序都有一个要求,那就是UI元素(如Button.TextBox等)必须由创建它的那个线程进行更新.WinForm在这方面 ...

  6. 理解Windows窗体和WPF中的跨线程调用

    你曾开发过Windows窗体程序,可能会注意到有时事件处理程序将抛出InvalidOperationException异常,信息为" 跨线程调用非法:在非创建控件的线程上访问该控件" ...

  7. Android中Activity、Window、ViewRootImpl与子线程更新UI

    三者层级关系 1.Window Window是一个抽象类,唯一的实现类是PhoneWindow Window分为三种类型应用Window.子Window.系统Window.子Window无法独立存在必 ...

  8. 为什么我的子线程更新了 UI 没报错?借此,纠正一些Android 程序员的一个知识误区...

    开门见山: 这个误区是:子线程不能更新 UI ,其应该分类讨论,而不是绝对的. 半小时前,我的 XRecyclerView 群里面,一位群友私聊我,问题是: 为什么我的子线程更新了 UI 没报错? 我 ...

  9. 使用LINQ更新集合中的所有对象

    有没有办法使用LINQ执行以下操作? foreach (var c in collection) {c.PropertyToSet = value; } 为了澄清,我想遍历集合中的每个对象,然后更新每 ...

最新文章

  1. Struts2三种传参方式(从jsp页面传到Action)
  2. 理解JS中的this的指向
  3. Android中四种启动模式,最容易理解的小白教程
  4. JZOJ 4161. 于神之怒
  5. C/C++基础知识点(四)
  6. RetrieveFavicon 获取任何站点的 favicon
  7. 满意度调查access模板_洪安镇推进综合便民服务中心标准化建设,着力提升群众满意度...
  8. react ant design路由配置
  9. 深度相机(三)--三种方案对比
  10. 基类显式继承接口,类继承基类时又继承同一接口,引发接口方法混乱(显式继承接口的弊端)...
  11. 301 302区别_302状态码代表什么,302状态码解决方法
  12. .a 和.o 合并成一个.a_污水处理A/A/O工艺调试运行体会
  13. 3dmax渲染出图噪点原因及解决方法
  14. nanomsg安装和测试
  15. C++ Learning
  16. 北大计算机专硕学费,北京大学专业硕士学费被曝高达2.2万元/年
  17. latex伪代码添加注释_【其他】如何用写代码的方式进行文字编辑 Markdown 的简明教程...
  18. 键盘的复制粘贴快捷键总是需要重复多次才起作用
  19. HTML5期末大作业:关于家乡景点介绍网页设计-------我的家乡金堂(9页) HTML+CSS+JavaScript
  20. 台式计算机读不到u盘怎么回事,电脑u盘读不出怎么办 快速解决u盘读不出方法盘点...

热门文章

  1. 让iis记录nginx反向代理真实ip
  2. Linux源码下Makefile详解(参照Documentation\kbuild\makefiles.txt和资料)-转
  3. Java发令枪ConcurrentExecutor之控制线程数,并发数
  4. 【iOS】Scale Fill、Aspect Fit 和 Aspect Fill 的区别(Content Mode)
  5. printf打印数组_(45)C++面试之把数组排成最小的数
  6. 知名的开源apm(Application Performance Management)工具
  7. Firefox 67不能勾选“以后自动采用相同的动作处理此类文件”解决方案
  8. Windows Server 2016-Windows控制台的新增功能
  9. lwip netbuf
  10. 多年JAVA 基础总结