一个优雅的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: }
浙公网安备 33010602011771号