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

  • 相关阅读:
    广告效果滚动
    判断背景图片是否加载成功
    css3创建多边形clip属性,可用来绘制不规则图形了
    不允许用户选中文本的两种方法
    栈类模板设计及应用
    HDOJ 题目类型
    极大团数量模板
    HDU 1522 Marriage is Stable 稳定婚姻匹配
    字符串类设计与应用
    正向与反向拓扑排序的区别(hdu 1285 确定比赛名次和hdu 4857 逃生)
  • 原文地址:https://www.cnblogs.com/TianFang/p/3481282.html
Copyright © 2011-2022 走看看