internal override void CacheBuildResult(string cacheKey, BuildResult result, long hashCode, DateTime utcStart) { if (!BuildResultCompiledType.UsesDelayLoadType(result)) { ICollection virtualPathDependencies = result.VirtualPathDependencies; CacheDependency dependencies = null; if (virtualPathDependencies != null) { dependencies = result.VirtualPath.GetCacheDependency(virtualPathDependencies, utcStart); if (dependencies != null) { result.UsesCacheDependency = true; } } if (result.CacheToMemory) { CacheItemPriority normal; BuildResultCompiledAssemblyBase base2 = result as BuildResultCompiledAssemblyBase; if (((base2 != null) && (base2.ResultAssembly != null)) && !base2.UsesExistingAssembly) { string assemblyCacheKey = BuildResultCache.GetAssemblyCacheKey(base2.ResultAssembly); Assembly assembly = (Assembly)this._cache.Get(assemblyCacheKey); if (assembly == null) { this._cache.UtcInsert(assemblyCacheKey, base2.ResultAssembly, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null); } CacheDependency dependency2 = new CacheDependency(0, null, new string[] { assemblyCacheKey }); if (dependencies != null) { AggregateCacheDependency dependency3 = new AggregateCacheDependency(); dependency3.Add(new CacheDependency[] { dependencies, dependency2 }); dependencies = dependency3; } else { dependencies = dependency2; } } string memoryCacheKey = GetMemoryCacheKey(cacheKey); if (result.IsUnloadable) { normal = CacheItemPriority.Normal; } else { normal = CacheItemPriority.NotRemovable; } CacheItemRemovedCallback onRemoveCallback = null; if (result.ShutdownAppDomainOnChange || (result is BuildResultCompiledAssemblyBase)) { if (this._onRemoveCallback == null) { this._onRemoveCallback = new CacheItemRemovedCallback(this.OnCacheItemRemoved); } onRemoveCallback = this._onRemoveCallback; } this._cache.UtcInsert(memoryCacheKey, result, dependencies, result.MemoryCacheExpiration, result.MemoryCacheSlidingExpiration, normal, onRemoveCallback); } } }
internal override void CacheBuildResult(string cacheKey, BuildResult result, long hashCode, DateTime utcStart) { ICollection virtualDependencies = result.VirtualPathDependencies; Debug.Trace("BuildResultCache", "Adding cache " + cacheKey + " in the memory cache"); CacheDependency cacheDependency = null; if (virtualDependencies != null) { cacheDependency = result.VirtualPath.GetCacheDependency(virtualDependencies, utcStart); // If we got a cache dependency, remember that in the BuildResult if (cacheDependency != null) { result.UsesCacheDependency = true; } } // If it should not be cached to memory, leave it alone if (!result.CacheToMemory) { return; } if (BuildResultCompiledType.UsesDelayLoadType(result)) { // If the result is delaying loading of assembly, then don't cache // to avoid having to load the assembly. return; } BuildResultCompiledAssemblyBase compiledResult = result as BuildResultCompiledAssemblyBase; if (compiledResult != null && compiledResult.ResultAssembly != null && !compiledResult.UsesExistingAssembly) { // Insert a new cache entry using the assembly path as the key string assemblyKey = GetAssemblyCacheKey(compiledResult.ResultAssembly); Assembly a = (Assembly)_cache.Get(assemblyKey); if (a == null) { Debug.Trace("BuildResultCache", "Adding marker cache entry " + compiledResult.ResultAssembly); // VSWhidbey 500049 - add as NotRemovable to prevent the assembly from being prematurely deleted _cache.UtcInsert(assemblyKey, compiledResult.ResultAssembly, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null); } else { Debug.Assert(a == compiledResult.ResultAssembly); } // Now create a dependency based on that key. This way, by removing that key, we are able to // remove all the pages that live in that assembly from the cache. CacheDependency assemblyCacheDependency = new CacheDependency(0, null, new string[] { assemblyKey }); if (cacheDependency != null) { // We can't share the same CacheDependency, since we don't want the UtcStart // behavior for the assembly. Use an Aggregate to put the two together. AggregateCacheDependency tmpDependency = new AggregateCacheDependency(); tmpDependency.Add(new CacheDependency[] { cacheDependency, assemblyCacheDependency }); cacheDependency = tmpDependency; } else { cacheDependency = assemblyCacheDependency; } } string key = GetMemoryCacheKey(cacheKey); // Only allow the cache item to expire if the result can be unloaded. Otherwise, // we may as well cache it forever (e.g. for Assemblies and Types). CacheItemPriority cachePriority; if (result.IsUnloadable) { cachePriority = CacheItemPriority.Default; } else { cachePriority = CacheItemPriority.NotRemovable; } CacheItemRemovedCallback onRemoveCallback = null; // If the appdomain needs to be shut down when the item becomes invalid, register // a callback to do the shutdown. if (result.ShutdownAppDomainOnChange || result is BuildResultCompiledAssemblyBase) { // Create the delegate on demand if (_onRemoveCallback == null) { _onRemoveCallback = new CacheItemRemovedCallback(OnCacheItemRemoved); } onRemoveCallback = _onRemoveCallback; } _cache.UtcInsert(key, result, cacheDependency, result.MemoryCacheExpiration, result.MemoryCacheSlidingExpiration, cachePriority, onRemoveCallback); }