一个优雅的Lock方案

虽然复杂,但是考虑到业务逻辑的需要,这套Lock方案还是相当不错的:

   1: CacheItem cacheItemBeforeLock = null;
   2: bool lockWasSuccessful = false;
   3:  
   4: do
   5: {
   6:     lock (inMemoryCache.SyncRoot)
   7:     {
   8:         if (inMemoryCache.Contains(key) == false)
   9:         {
  10:             cacheItemBeforeLock = new CacheItem(key, addInProgressFlag, CacheItemPriority.NotRemovable, null);
  11:             inMemoryCache[key] = cacheItemBeforeLock;
  12:         }
  13:         else
  14:         {
  15:             cacheItemBeforeLock = (CacheItem)inMemoryCache[key];
  16:         }
  17:  
  18:         lockWasSuccessful = Monitor.TryEnter(cacheItemBeforeLock);
  19:     }
  20:  
  21:     if (lockWasSuccessful == false)
  22:     {
  23:         Thread.Sleep(0);
  24:     }
  25: } while (lockWasSuccessful == false);
  26:  
  27: try
  28: {
  29:     cacheItemBeforeLock.TouchedByUserAction(true);
  30:  
  31:     CacheItem newCacheItem = new CacheItem(key, value, scavengingPriority, refreshAction, expirations);
  32:     try
  33:     {
  34:         backingStore.Add(newCacheItem);
  35:         cacheItemBeforeLock.Replace(value, refreshAction, scavengingPriority, expirations);
  36:         inMemoryCache[key] = cacheItemBeforeLock;
  37:     }
  38:     catch
  39:     {
  40:         backingStore.Remove(key);
  41:         inMemoryCache.Remove(key);
  42:         throw;
  43:     }
  44:  
  45:     if (scavengingPolicy.IsScavengingNeeded(inMemoryCache.Count))
  46:     {
  47:         cacheScavenger.StartScavenging();
  48:     }
  49:  
  50:     instrumentationProvider.FireCacheUpdated(1, inMemoryCache.Count);
  51: }
  52: finally
  53: {
  54:     Monitor.Exit(cacheItemBeforeLock);
  55: }
posted @ 2008-12-17 01:20  new 维生素C.net()  阅读(379)  评论(0编辑  收藏  举报