我正在尝试实现一个通用的线程安全的Cache方法,我想知道如何在其中实现锁定。
看起来应该是这样的:
//private static readonly lockObject = new Object();
public T GetCache<T>(string key, Func<T> valueFactory...)
{
// try to pull from cache here
lock (lockObject) // I don't want to use static object lock here because then every time a lock is performed, all cached objects in my site have to wait, regarding of the cache key.
{
// cache was empty before we got the lock, check again inside the lock
// cache is still empty, so retreive the value here
// store the value in the cache here
}
// return the cached value here
}
答案 0 :(得分:4)
这是您使用mutex的情况 Mutex 可以使用密钥锁定以锁定该密钥 - 但您无法更改相同的资源!
public T GetCache<T>(string key, Func<T> valueFactory...)
{
// note here that I use the key as the name of the mutex
// also here you need to check that the key have no invalid charater
// to used as mutex name.
var mut = new Mutex(true, key);
try
{
// Wait until it is safe to enter.
mut.WaitOne();
// here you create your cache
}
finally
{
// Release the Mutex.
mut.ReleaseMutex();
}
}
1)一种情况是我们在所有池中使用公共资源,所有线程。公共资源可以是文件,也可以是数据库本身。
在常见资源中,我们需要使用互斥。
2)第二种情况是当我们使用仅对池内部可见的变量时 - 不同的池无法看到该资源。例如,静态列表&lt;&gt; ,静态字典等。此静态变量,数组只能在池内访问,并且它们在不同池中不同。
在第二种情况下, lock()是最简单和最常用的使用方式。
现在,当我们有一个静态字典,我们长时间保留并在那里进行过多的读/写操作时,更快的方法是避免整个程序等待,ReaderWriterLockSlim
您可以从此处获取完整示例:ReaderWriterLockSlim
使用ReaderWriterLockSlim,我们可以在不需要时避免锁定 - 我们不需要在读取时锁定静态值 - 只有在我们写入它们时。所以我可以建议我们将它们用作缓存的静态值。
映像,好像运行的不同程序相互隔离但服务于来自用户的传入请求。每个游泳池都有自己的世界,他们没有相互沟通。每个池都有初始化,静态值和生命。要在池之间拥有一些公共资源,您需要一些其他第三个程序,如数据库,如磁盘上的文件,如服务。
因此,如果您有许多池(Web园)将它们与公共资源同步,则需要使用互斥锁。要在内部同步它们,请使用锁定。
IIS app pools, worker processes, app domains
Lifetime of ASP.NET Static Variable
答案 1 :(得分:1)
我刚刚找到了LazyCache lib。我还没有在生产中试过它。
IAppCache cache = new CachingService();
ComplexObject cachedResults = cache.GetOrAdd("uniqueKey",
() => methodThatTakesTimeOrResources());
答案 2 :(得分:0)
.NET ConcurrentDictionary<TKey, TItem>
通过为每个密钥哈希创建单独的锁来实现内部。这样做的好处是只锁定一个相关的哈希值,即使在处理项目添加和删除时也是如此。