internal static void OnCacheEntryRemovedCallback(CacheEntryRemovedArguments arguments) { MemoryCache cache = arguments.Source as MemoryCache; SentinelEntry entry = arguments.CacheItem.Value as SentinelEntry; CacheEntryRemovedReason reason = arguments.RemovedReason; switch (reason) { case CacheEntryRemovedReason.Expired: break; case CacheEntryRemovedReason.ChangeMonitorChanged: if (entry.ExpensiveObjectDependency.HasChanged) { // If the expensiveObject has been removed explicitly by Cache.Remove, // return from the SentinelEntry removed callback // thus effectively removing the SentinelEntry from the cache. return; } break; case CacheEntryRemovedReason.Evicted: Dbg.Fail("Reason should never be CacheEntryRemovedReason.Evicted since the entry was inserted as NotRemovable."); return; default: // do nothing if reason is Removed or CacheSpecificEviction return; } // invoke update callback try { CacheEntryUpdateArguments args = new CacheEntryUpdateArguments(cache, reason, entry.Key, null); entry.CacheEntryUpdateCallback(args); Object expensiveObject = (args.UpdatedCacheItem != null) ? args.UpdatedCacheItem.Value : null; CacheItemPolicy policy = args.UpdatedCacheItemPolicy; // Only update the "expensive" object if the user returns a new object, // a policy with update callback, and the change monitors haven't changed. (Inserting // with change monitors that have already changed will cause recursion.) if (expensiveObject != null && IsPolicyValid(policy)) { cache.Set(entry.Key, expensiveObject, policy); } else { cache.Remove(entry.Key); } } catch { cache.Remove(entry.Key); // Review: What should we do with this exception? } }