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中跨线程更新集合的更多相关文章

  1. WPF Dispatcher.BeginInvoke子线程更新UI

    在开发WPF应用时出现:”调用线程无法访问此对象,因为另一个线程拥有该对象.“ 是因为UI线程是WPF应用的主线程,若尝试子线程更新UI线程应使用Dispatcher.BeginInvoke()或者I ...

  2. WPF 非UI线程更新UI界面的各种方法小结

    转载:https://www.cnblogs.com/bdbw2012/articles/3777594.html 我们知道只有UI线程才能更新UI界面,其他线程访问UI控件被认为是非法的.但是我们在 ...

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

    Winform中的控件是绑定到特定的线程的(一般是主线程),这意味着从另一个线程更新主线程的控件不能直接调用该控件的成员. 控件绑定到特定的线程这个概念如下: 为了从另一个线程更新主线程的Window ...

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

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

  5. Winform非UI线程更新UI界面的各种方法小结

    我们知道只有UI线程才能更新UI界面,其他线程访问UI控件被认为是非法的.但是我们在进行异步操作时,经常需要将异步执行的进度报告给用户,让用户知道任务的进度,不至于让用户误认为程序“死掉了”,特别是对 ...

  6. C# 跨线程更新 UI

    Winforms 跨线程更新 UI 在 Winforms 中, 所有的控件都包含 InvokeRequired 属性, 如果我们要更新UI,通过它我们可以判断是否需要调用 [Begin]Invoke. ...

  7. 非UI线程更新UI界面的各种方法小结

    转载:https://www.cnblogs.com/xiashengwang/archive/2012/08/18/2645541.html 我们知道只有UI线程才能更新UI界面,其他线程访问UI控 ...

  8. C#的变迁史 - C# 4.0 之线程安全集合篇

    作为多线程和并行计算不得不考虑的问题就是临界资源的访问问题,解决临界资源的访问通常是加锁或者是使用信号量,这个大家应该很熟悉了. 而集合作为一种重要的临界资源,通用性更广,为了让大家更安全的使用它们, ...

  9. 学习通过Thread+Handler实现非UI线程更新UI组件

    [Android线程机制] 出于性能考虑,Android的UI操作并不是线程安全的,这就意味着如果有多个线程并发操作UI组件,可能导致线程安全问题.为了解决这个问题,Android制定了一条简单的规则 ...

随机推荐

  1. CSS3学习笔记之立体线框球形动画

    效果截图: HTML代码: <div class="ball-box"> <div class="ball"> <div clas ...

  2. Android4.4中WebView无法显示图片解决方案

    在Android4.4之前我们在使用WebView时为了提高加载速度我设置了(myWebView.getSettings().setBlockNetworkImage(true);//图片加载放在最后 ...

  3. noip2016 普及组

    T1 买铅笔 题目传送门 #include<cstdio> #include<cstring> #include<algorithm> using namespac ...

  4. HDU2444(判断是否为二分图,求最大匹配)

    The Accomodation of Students Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  5. expect基础及实例

    expect基础及实例 http://blog.csdn.net/zhuying_linux/article/details/6900805

  6. Selenium2+python自动化57-捕获异常(NoSuchElementException)【转载】

    前言 在定位元素的时候,经常会遇到各种异常,为什么会发生这些异常,遇到异常又该如何处理呢? 本篇通过学习selenium的exceptions模块,了解异常发生的原因. 一.发生异常 1.打开博客首页 ...

  7. [转载]数据层的多租户浅谈(SAAS多租户数据库设计)

    原文:http://www.ibm.com/developerworks/cn/java/j-lo-dataMultitenant/index.html 在上一篇“浅析多租户在 Java 平台和某些 ...

  8. 【UOJ UNR #1】火车管理 可持久化线段树

    用可持久化线段树维护每个站的第一辆车和每个站的前一次更新的位置即可. #include<iostream> #include<cstring> #include<cstd ...

  9. set注入

    顾名思义set注入必须要有set方法. 基本类型的注入.引用类型注入.List注入.Set注入.Map注入.Properties注入 public class person { private car ...

  10. 训练指南 UVA - 11419(二分图最小覆盖数)

    layout: post title: 训练指南 UVA - 11419(二分图最小覆盖数) author: "luowentaoaa" catalog: true mathjax ...