我有一个静态类,用于处理常用数据的缓存读/写。
代码是这样的:
public static T GetFromCache<T>(double seconds, string cacheId, Func<T> method) where T : class
{
HttpContext ctx = HttpContext.Current;
object temp = null;
temp = ctx.Cache[cacheId];
if (temp == null)
{
lock (Sync)
{
temp = ctx.Cache[cacheId];
if (temp == null)
{
temp = method.Invoke();
AddToCache(temp as T, seconds, cacheId);
return temp as T;
}
}
}
if (temp is T)
{
return (T)temp;
}
return null;
}
各种调用者使用该代码从缓存中读取数据并将数据写入缓存。
现在我有一个Sync对象(private static readonly object Sync = new object();
),当数据写入缓存时会被锁定。
由于此代码由多个调用者调用,我想创建一个Sync对象列表,每个调用者一个。 (使用调用者我不是指用户,而是调用代码。然后我会通过参数caller
的签名来识别method
我想要的原因是每一段调用代码都可以拥有它自己的锁对象;否则(我认为)来自不同调用者的每个对此缓存控制器的调用将使用相同的锁对象。然后,国家列表的缓存也将锁定状态列表的缓存,并且使用两个不同的锁定对象,它们将不会彼此相同。
然后我会使用CacheItemRemovedCallback
方法从列表中删除锁定项。
问题是:我该怎么做?
答案 0 :(得分:1)
通过为每个用户设置一个Sync对象将违反同步的目的,因为每个用户将拥有自己的锁,并且有可能对于相同的cacheId,您将最终多次调用该方法。这可能会导致数据不一致。
如果您希望为每个用户保留一个Sync对象,那么利用会话变量或每个用户缓存或类似的东西是好的。否则每个用户实际上最终会互相搞砸&#39; s cacheId结果。
如果你有一个场景,可以有多个数据读者,但一次只有一个用户可以写,然后尝试使用ReaderWriterLockSlim。与多用户场景中的锁定相比,这非常快。
<强> UPDATE1 强>
考虑到cacheId是唯一的,并且在调用者之间不常见。您可以使用以下代码。
这里不需要锁定。原因,HttpContext.Cache是ThreadSafe。意思是,您可以读取/保存值到Cache。但是,如果值引用本身在多个并发调用之间共享,那么请同步它。
public static T GetFromCache<T>(double seconds, string cacheId, Func<T> method) where T : class
{
HttpContext ctx = HttpContext.Current;
object temp = null;
temp = ctx.Cache[cacheId];
if (temp == null)
{
temp = method.Invoke();
AddToCache(temp as T, seconds, cacheId);
return temp as T;
}
}
此致