可移植类库的ConcurrentDictionary替代品

托马斯·列夫斯克

我正在编写一个针对.NET 4.5,Windows Store应用程序和Windows Phone 8的可移植类库。我需要一种有效的内存中缓存机制,因此我在考虑使用ConcurrentDictionary<K,V>,但是在WP8中不可用。

会有很多读取操作,而写入操作则相对较少,因此理想情况下,我想要一个支持从多个线程进行无锁读取并由一个线程进行写入的集合。根据MSDN非泛型Hashtable具有该属性,但不幸的是,它在PCL中不可用...

PCL中是否有另一个符合此要求的收集类?如果没有,那么在不锁定读取的情况下实现线程安全的好方法是什么?(写锁定是可以的,因为它不会经常发生)


编辑:感谢JaredPar的指导下,我终于实现我的缓存在一个完全无锁的方式,利用ImmutableDictionary<TKey, TValue>Microsoft.Bcl.Immutable

class Cache<TKey, TValue>
{
    private IImmutableDictionary<TKey, TValue> _cache = ImmutableDictionary.Create<TKey, TValue>();

    public TValue GetOrAdd(TKey key, [NotNull] Func<TKey, TValue> valueFactory)
    {
        valueFactory.CheckArgumentNull("valueFactory");

        TValue newValue = default(TValue);
        bool newValueCreated = false;
        while (true)
        {
            var oldCache = _cache;
            TValue value;
            if (oldCache.TryGetValue(key, out value))
                return value;

            // Value not found; create it if necessary
            if (!newValueCreated)
            {
                newValue = valueFactory(key);
                newValueCreated = true;
            }

            // Add the new value to the cache
            var newCache = oldCache.Add(key, newValue);
            if (Interlocked.CompareExchange(ref _cache, newCache, oldCache) == oldCache)
            {
                // Cache successfully written
                return newValue;
            }

            // Failed to write the new cache because another thread
            // already changed it; try again.
        }
    }

    public void Clear()
    {
        _cache = _cache.Clear();
    }
}
Jaredpar

要考虑的一种选择是在不可变的搜索树上编写一个薄的外观。网络上有几种不可变的搜索树可供选择。我通常以Eric Lipperts的出色文章为依据

将其用作后备数据结构将使您无锁。也可以使用CAS以无锁的方式写入树中。这将比ConcurrentDictionary查找慢一些,因为查找是O(Log(N))而不是O(1)。但这应该可以帮你

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章