这些是我的方法:
public static string CacheKey(string userName)
{
return "MyObj" + userName;
}
private static MyObj CachedObj(string userName)
{
string cacheKey = CacheKey(userName);
MyObj cachedBW = HttpRuntime.Cache[cacheKey] as MyObj;
if (cachedBW == null)
{
Mutex bwMutex = new Mutex(false, cacheKey);
if (bwMutex.WaitOne(Constant.LOCKING_TIMEOUT))
{
try
{
cachedBW = HttpRuntime.Cache[cacheKey] as MyObj;
if (cachedBW == null)
{
cachedBW = InitialisedBusinessWrapper();
HttpRuntime.Cache.Add(cacheKey, cachedBW, null,
System.Web.Caching.Cache.NoAbsoluteExpiration,
TimeSpan.FromMinutes(INACTIVITY_TIMEOUT), CacheItemPriority.Normal, null);
return cachedBW;
}
else
return cachedBW;
}
finally
{
bwMutex.ReleaseMutex();
}
}
else
throw new Exception("Timed out waiting");
}
else
return cachedBW;
}
我一次又一次地访问路径MyObjUsername
,这是我的缓存密钥被拒绝。你看到我的代码有什么问题吗?我该如何解决?在我的控制器操作中调用这些方法,并且可以使用相同的用户名登录特定的多个用户。
答案 0 :(得分:0)
您需要锁定HttpRuntime.Cache对象而不是密钥
HttpRuntime.Cache不是线程安全的
我更喜欢使用带锁定键的MemoryCache,因为MemoryCache不是线程安全的:
答案 1 :(得分:0)
// this is to lock multiple calls to the static method and lock the Cache
// must not be inside the static method
private static readonly object _lock = new object();
private static MyObj CachedObj(string userName)
{
lock(_lock){
//here safe to add, update or delete from the Cache
// since _lock is a global lock to all static method calls
}
}
锁定键不能在静态方法
中答案 2 :(得分:0)
此代码可以让您更轻松:
public static class WebCache
{
#region Private Fields
private static readonly MemoryCache _cache = MemoryCache.Default;
private static readonly HashSet<string> _keysList = new HashSet<string>();
private static readonly object _lock = new object();
#endregion Private Fields
#region Public Methods
public static T GetUpdate<T>(string key, Func<T> getValue)
{
if (_cache[key] == null) { Update(key, getValue); }
return (T)_cache[key];
}
public static void Remove(string key)
{
lock (_lock)
{
_cache.Remove(key);
_keysList.Remove(key);
}
}
public static void RemoveAll()
{
string[] keyArray = new string[_keysList.Count];
_keysList.CopyTo(keyArray);
foreach (string key in keyArray) { lock (_lock) { _cache.Remove(key); } }
lock (_lock) { _keysList.Clear(); }
keyArray.ExClear();
}
public static void Update<T>(string key, Func<T> getValue)
{
CacheItemPolicy policy = new CacheItemPolicy
{
AbsoluteExpiration = ObjectCache.InfiniteAbsoluteExpiration,
SlidingExpiration = new TimeSpan(2, 0, 0),
RemovedCallback =
(arg) => { lock (_lock) { _keysList.Remove(arg.CacheItem.Key); } },
Priority = CacheItemPriority.Default
};
Remove(key);
lock (_lock) { _cache.Add(key, getValue(), policy); _keysList.Add(key); }
}
#endregion Public Methods
}
用法:
object myCachedObj = WebCache.GetUpdate("KeyName", () => GetRequiredObject());