Kel*_*ron 2 c# asp.net caching dictionary thread-safety
我对多线程非常陌生,由于某种原因,这门课给我带来的麻烦比应该多.
我在ASP.net缓存中设置了一个字典 - 它经常被查询单个对象,偶尔枚举,并且很少写入.我会注意到字典数据几乎从未改变过,我打算让它每天过期,并在离开缓存时从数据库重建回调.
我相信只要没有编写字典,枚举和密钥访问就是安全的.我在想一个基于ReaderWriterLockSlim的包装类是要走的路,但我在几点上模糊了.
如果我使用Lock,我相信我可以锁定令牌或我正在保护的实际对象.我没有看到如何使用ReaderWriter Lock做类似的事情.我是否认为我的包装器的多个实例无法正确锁定,因为ReaderWriterLocks不在彼此的范围内?
编写这样的包装器的最佳实践是什么?将其构建为静态几乎看起来是多余的,因为主要对象由缓存维护.单身人士似乎不赞成,我担心上面提到的个别实例的范围界定问题.
我已经看到了一些类似包装器的实现,但我无法回答这些问题.我只是想确保我对我正在做的事情有一个坚定的把握,而不是削减和粘贴我的方式.非常感谢您的帮助!
**编辑:希望这是我想要找到的更清晰的总结 - **
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();
Run Code Online (Sandbox Code Playgroud)
我是否认为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>();
Run Code Online (Sandbox Code Playgroud)
在MSDN上的ReaderWriterLockSlim的帮助页面上还有一个更完整的示例.让它变得通用并不难.
编辑回答您的新问题 -
1.)你是正确的wrapA和wrapB不会互动.他们都有自己的ReaderWriterLockSlim实例.
2.)如果您需要在所有包装类中使用共享锁,那么它必须是静态的.
| 归档时间: |
|
| 查看次数: |
4308 次 |
| 最近记录: |