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

  • 相关阅读:
    数据库高级链表查询,重点可以多看看
    数据库多表查询,一对一关系,一对多关系,多对多关系
    Django基础
    前端之JavaScript
    前端之Jquery
    CF888E Maximum Subsequence-折半搜索
    HNOI2010 平面图判定
    CEOI 2011Traffic
    LuoguP1710 地铁涨价
    Luogu2059 卡牌游戏-概率DP
  • 原文地址:https://www.cnblogs.com/TianFang/p/3481282.html
Copyright © 2011-2022 走看看