2015-04-01 73 views
0

我有一個字典(併發),用於映射一個對象的ID到另一個。根據輸入密鑰獲取值id相當昂貴,所以我想將字典保存在服務器緩存中。訪問和更新緩存字典

我有一個方法的第一臉紅嘗試做到這一點,但它只是「感覺」好像有可能是一個更好的方式來做到這一點:

private string GetItem(string cacheKey, string itemKey) 
{ 
    string sfAccountId = null; 
    ConcurrentDictionary<string, string> sfAccountMap = 
      Context.Cache[cacheKey] as ConcurrentDictionary<string, string>; 
    if(sfAccountMap == null) 
    { 
     lock(cacheLock) 
     { 
      sfAccountMap = Context.Cache[cacheKey] as ConcurrentDictionary<string, string>; 
      if(sfAccountMap == null) 
      { 
       sfAccountMap = new ConcurrentDictionary<string, string>(); 
       sfAccountId = ExpensiveMethodReturnsString(); 
       if(!String.IsNullOrEmpty(sfAccountId)) 
       { 
        sfAccountMap.TryAdd(itemKey, sfAccountId); 
       } 
       Context.Cache[cacheKey] = sfAccountMap; 
      } 
     } 
    } 
    else 
    { 
     if(sfAccountMap.ContainsKey(itemKey)) 
     { 
      sfAccountMap.TryGetValue(itemKey, out sfAccountId); 
     } 
     else 
     { 
      sfAccountMap.TryAdd(itemKey, ExpensiveMethodReturnsString()); 
      lock(cacheLock) 
      { 
       Context.Cache[cacheKey] = sfAccountMap; 
      } 
     } 
    } 
    return sfAccountId; 
} 

回答

1

看來你的代碼可以簡化,同時仍然在做現在正在做的事情。

private ConcurrentDictionary<string, string> GetCachedAccountMap(string cacheKey) 
{ 
    var map = Context.Cache[cacheKey] as ConcurrentDictionary<string, string>; 
    if (map == null) 
    { 
     lock (cacheLock) 
     { 
      map = Context.Cache[cacheKey] as ConcurrentDictionary<string, string>; 
      if (map == null) 
       map = Context.Cache[cacheKey] = new ConcurrentDictionary<string, string>(); 
     } 
    } 
    return map; 
} 

private string GetItem(string cacheKey, string itemKey) 
{ 
    return GetCachedAccountMap(cacheKey) 
     .GetOrAdd(itemKey, k => ExpensiveMethodReturnsString()); 
} 

注:因爲它是不太可能有緩存的併發訪問,而該帳戶的地圖還沒有出現,而且似乎也不是那麼壞在非常特殊的情況下,如果你做一個額外的分配並致電昂貴的方法,GetCachedAccountMap方法可以進一步簡化,不使用任何鎖。

private ConcurrentDictionary<string, string> GetCachedAccountMap(string cacheKey) 
{ 
    var map = Context.Cache[cacheKey] as ConcurrentDictionary<string, string>; 
    if (map == null) 
     map = Context.Cache[cacheKey] = new ConcurrentDictionary<string, string>(); 
    return map; 
} 
+0

啊,是的,這看起來更好。 – Nate222 2015-04-01 20:52:12