我是多线程技术的新手,由于某种原因,该类给我带来了更多的麻烦。

我正在ASP.net缓存中设置字典-它将经常查询单个对象,偶尔会枚举,并且写得很少。我会注意到字典数据几乎从未改变,我打算让它每天过期,并在其离开缓存时通过回调从数据库重建。

我相信,只要不编写字典,通过键进行的枚举和访问都是安全的。我在想一个基于ReaderWriterLockSlim的包装器类是可行的方法,但是我在几点上很模糊。

如果使用Lock,我相信可以锁定令牌或要保护的实际对象。我看不到如何使用ReaderWriter Lock执行类似的操作。我是否正确地认为包装器的多个实例将无法正确锁定,因为ReaderWriterLocks不在彼此的范围之内?

编写这样的包装的最佳实践是什么?将其构建为静态似乎几乎是多余的,因为主要对象由缓存维护。 Singleton似乎不满意,我担心上述针对单个实例的作用域问题。

我已经看到了一些类似包装器的实现,但是我无法回答这些问题。我只想确保自己对正在做的事情有把握,而不是随意粘贴。非常感谢您的帮助!



**编辑:希望这是我要找出的更清晰的摘要-**

1.我认为锁不会影响基础数据并且作用域与其他变量一样正确吗?

举例来说,我有以下内容-

MyWrapperClass
{
    ReaderWriterLockSlim lck = new ReaderWriterLockSlim();
    Do stuff with this lock on the underlying cached dictionary object...
}

MyWrapperClass wrapA = new MyWrapperClass();
MyWrapperClass wrapB = new MyWrapperClass();


我是不是认为wrapA锁和wrapB锁不会相互作用,并且如果wrapA和wrapB都尝试操作,那将是不安全的吗?

2.如果是这种情况,“共享”锁数据的最佳实践方法是什么?

这是一个Asp.net应用程序-将有多个页面需要访问数据,这就是为什么我要首先这样做的原因。确保各种包装使用同一锁的最佳实践是什么?我的包装器应该是所有线程都使用的静态还是单例,如果不是,那么更优雅的选择是什么?

最佳答案

您在缓存中有多个字典对象,并且您希望每个对象都独立锁定。 “最佳”方法是仅使用一个简单的类为您完成此操作。

public class ReadWriteDictionary<K,V>
{
    private readonly Dictionary<K,V> dict = new Dictionary<K,V>();
    private readonly ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();

    public V Get(K key)
    {
        return ReadLock(() => dict[key]);
    }

    public void Set(K key, V value)
    {
        WriteLock(() => dict.Add(key, value));
    }

    public IEnumerable<KeyValuePair<K, V>> GetPairs()
    {
        return ReadLock(() => dict.ToList());
    }

    private V2 ReadLock<V2>(Func<V2> func)
    {
        rwLock.EnterReadLock();
        try
        {
            return func();
        }
        finally
        {
            rwLock.ExitReadLock();
        }
    }

    private void WriteLock(Action action)
    {
        rwLock.EnterWriteLock();
        try
        {
            action();
        }
        finally
        {
            rwLock.ExitWriteLock();
        }
    }
}

Cache["somekey"] = new ReadWriteDictionary<string,int>();


ReaderWriterLockSlim on MSDN的帮助页面上还有一个更完整的示例。使它通用并不难。

编辑要回答您的新问题-

1.)你是正确的wrapA和wrapB将不会交互。它们都有自己的ReaderWriterLockSlim实例。

2)如果您需要所有包装器类之间的共享锁,则它必须是静态的。

关于c# - 具有ReaderWriterLockSlim的C#词典,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1330352/

10-11 00:14