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

  • 相关阅读:
    iOS 音频视频图像合成那点事
    Android低功耗蓝牙(BLE)使用详解
    android实现超酷的腾讯视频首页和垂直水平网格瀑布流一揽子效果
    基于vue单页应用的例子
    Android 6.0 超级简单的权限申请 (Permission)
    ubuntu创建Centos7镜像&&配置运行环境
    Scikit-learn方法使用总结
    解决TensorFlow最新代码编译错误问题
    jQuery 基础
    数据交换格式 —— JSON(JavaScript Object Notation)
  • 原文地址:https://www.cnblogs.com/TianFang/p/3481282.html
Copyright © 2011-2022 走看看