WPF 设置资源字典多线程安全读写方法

本文探讨了WPF中ResourceDictionary的多线程安全问题,介绍了如何通过设置CanBeAccessedAcrossThreads属性确保线程安全读写,并提供了一个辅助类来实现这一功能。测试表明,正确设置该属性可以避免线程冲突,提高应用性能。同时警告在XAML中使用Contains方法可能存在的风险,并分享了作者的博客和学习资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在 WPF 中,使用 ResourceDictionary 本身不会受到创建线程同步影响,意味着可以在任意的线程创建 ResourceDictionary 资源字典,然后在任意线程使用。但是此时的读写需要有时间上的差距,否则将会多线程读写不安全。在 ResourceDictionary 有一个 CanBeAccessedAcrossThreads 属性用来决定在进行读写的时候是否加上锁,但这个属性是内部的,需要通过黑科技更改才能用上

依据 WPF 的源代码,可以看到 ResourceDictionary 类继承了 IDictionary 接口,也开放了 Add 和 Clear 和 Contains 等方法,在这些方法的实现里面,都会先判断 CanBeAccessedAcrossThreads 属性的值,然后决定是否加上锁进行安全读写

        public void Add(object key, object value)
        {
            // Seal styles and templates within App and Theme dictionary
            SealValue(value);

            if (CanBeAccessedAcrossThreads)
            {
                lock(((ICollection)this).SyncRoot)
                {
                    AddWithoutLock(key, value);
                }
            }
            else
            {
                AddWithoutLock(key, value);
            }

        }

        /// <summary>
        ///     Removes all elements from the IDictionary.
        /// </summary>
        public void Clear()
        {
            if (CanBeAccessedAcrossThreads)
            {
                lock(((ICollection)this).SyncRoot)
                {
                    ClearWithoutLock();
                }
            }
            else
            {
                ClearWithoutLock();
            }
        }

因此想要进行多线程安全的读写就需要设置 CanBeAccessedAcrossThreads 属性,而这个属性的定义如下

        internal bool CanBeAccessedAcrossThreads
        {
            get { return ReadPrivateFlag(PrivateFlags.CanBeAccessedAcrossThreads); }
            set { WritePrivateFlag(PrivateFlags.CanBeAccessedAcrossThreads, value); }
        }

也就是

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值