internal override void CacheBuildResult(string cacheKey, BuildResult result, long hashCode, DateTime utcStart) { // If it should not be cached to disk, leave it alone if (!result.CacheToDisk) { return; } // VSWhidbey 564168 don't save to disk if already shutting down, otherwise we might // be persisting assembly that was compiled with obsolete references. // Since we are shutting down and not creating any cache, delete the compiled result // as it will not be used in future. if (HostingEnvironment.ShutdownInitiated) { BuildResultCompiledAssemblyBase compiledResult = result as BuildResultCompiledAssemblyBase; // DevDiv2 880034: check if ResultAssembly is null before calling GetName(). // UsesExistingAssembly could be true in updatable compilation scenarios. if (compiledResult != null && compiledResult.ResultAssembly != null && !compiledResult.UsesExistingAssembly) { MarkAssemblyAndRelatedFilesForDeletion(compiledResult.ResultAssembly.GetName().Name); } return; } string preservationFile = GetPreservedDataFileName(cacheKey); PreservationFileWriter pfw = new PreservationFileWriter(PrecompilationMode); pfw.SaveBuildResultToFile(preservationFile, result, hashCode); }
internal static ReferenceAssemblyType GetPathToReferenceAssembly(Assembly a, out string path, ICollection <BuildErrorEventArgs> errors, ICollection <BuildWarningEventArgs> warnings, bool checkDependencies) { lock (s_lock) { if (AssemblyLocations.TryGetValue(a, out path)) { return(ReferenceAssemblyTypes[a]); } } if ((TargetFrameworkReferenceAssemblyPaths == null) || (TargetFrameworkReferenceAssemblyPaths.Count == 0)) { path = Util.GetAssemblyCodeBase(a); return(ReferenceAssemblyType.FrameworkAssembly); } AssemblyResolutionResult result = null; ReferenceAssemblyType nonFrameworkAssembly = ReferenceAssemblyType.NonFrameworkAssembly; if (BuildResultCompiledAssemblyBase.AssemblyIsInCodegenDir(a)) { path = Util.GetAssemblyCodeBase(a); } else { nonFrameworkAssembly = GetPathToReferenceAssembly(a, out path, errors, warnings, checkDependencies, true, out result); } StoreResults(a, path, result, nonFrameworkAssembly); return(nonFrameworkAssembly); }
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 void RemoveAssemblyAndCleanupDependencies(BuildResultCompiledAssemblyBase compiledResult) { if ((compiledResult != null) && (((compiledResult != null) && (compiledResult.ResultAssembly != null)) && !compiledResult.UsesExistingAssembly)) { this.RemoveAssemblyAndCleanupDependencies(compiledResult.ResultAssembly.GetName().Name); } }
internal override void GetPreservedAttributes(PreservationFileReader pfr) { base.GetPreservedAttributes(pfr); Assembly preservedAssembly = BuildResultCompiledAssemblyBase.GetPreservedAssembly(pfr); string attribute = pfr.GetAttribute("type"); this.ResultType = preservedAssembly.GetType(attribute, true); }
internal void RemoveAssemblyAndCleanupDependenciesShuttingDown(BuildResultCompiledAssemblyBase compiledResult) { if ((compiledResult != null) && (((compiledResult != null) && (compiledResult.ResultAssembly != null)) && !compiledResult.UsesExistingAssembly)) { string name = compiledResult.ResultAssembly.GetName().Name; lock (this._dependentAssemblies) { this.RemoveAssemblyAndCleanupDependenciesNoLock(name); } } }
internal void RemoveAssemblyAndCleanupDependencies(BuildResultCompiledAssemblyBase compiledResult) { if (compiledResult == null) { return; } if (compiledResult != null && compiledResult.ResultAssembly != null && !compiledResult.UsesExistingAssembly) { RemoveAssemblyAndCleanupDependencies(compiledResult.ResultAssembly.GetName().Name); } }
// Since we are shutting down, we will just create the .delete files to mark the files for deletion, // and not try to get the compilation lock. internal void RemoveAssemblyAndCleanupDependenciesShuttingDown(BuildResultCompiledAssemblyBase compiledResult) { if (compiledResult == null) { return; } if (compiledResult != null && compiledResult.ResultAssembly != null && !compiledResult.UsesExistingAssembly) { string assemblyName = compiledResult.ResultAssembly.GetName().Name; lock (_dependentAssemblies) { RemoveAssemblyAndCleanupDependenciesNoLock(assemblyName); } } }
internal override void CacheBuildResult(string cacheKey, BuildResult result, long hashCode, DateTime utcStart) { if (result.CacheToDisk) { if (HostingEnvironment.ShutdownInitiated) { BuildResultCompiledAssemblyBase base2 = result as BuildResultCompiledAssemblyBase; if (base2 != null) { this.MarkAssemblyAndRelatedFilesForDeletion(base2.ResultAssembly.GetName().Name); } } else { string preservedDataFileName = this.GetPreservedDataFileName(cacheKey); new PreservationFileWriter(this.PrecompilationMode).SaveBuildResultToFile(preservedDataFileName, result, hashCode); } } }
internal static ReferenceAssemblyType GetPathToReferenceAssembly(Assembly a, out string path, ICollection <BuildErrorEventArgs> errors, ICollection <BuildWarningEventArgs> warnings, bool checkDependencies) { lock (s_lock) { if (AssemblyLocations.TryGetValue(a, out path)) { return(ReferenceAssemblyTypes[a]); } } // If there are no reference assemblies available, just use the path to the loaded assembly. if (TargetFrameworkReferenceAssemblyPaths == null || TargetFrameworkReferenceAssemblyPaths.Count == 0) { path = System.Web.UI.Util.GetAssemblyCodeBase(a); return(ReferenceAssemblyType.FrameworkAssembly); } AssemblyResolutionResult result = null; ReferenceAssemblyType referenceAssemblyType = ReferenceAssemblyType.NonFrameworkAssembly; // If the assembly is generated by us, it is a non framework assembly and does not need to be resolved. if (BuildResultCompiledAssemblyBase.AssemblyIsInCodegenDir(a)) { path = System.Web.UI.Util.GetAssemblyCodeBase(a); } else { // Try using the assembly full name. referenceAssemblyType = GetPathToReferenceAssembly(a, out path, errors, warnings, checkDependencies, true /*useFullName*/, out result); } StoreResults(a, path, result, referenceAssemblyType); return(referenceAssemblyType); }
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); }
internal void RemoveAssemblyAndCleanupDependencies(BuildResultCompiledAssemblyBase compiledResult) { if (compiledResult == null) return; if (compiledResult != null && compiledResult.ResultAssembly != null && !compiledResult.UsesExistingAssembly) { RemoveAssemblyAndCleanupDependencies(compiledResult.ResultAssembly.GetName().Name); } }
// Since we are shutting down, we will just create the .delete files to mark the files for deletion, // and not try to get the compilation lock. internal void RemoveAssemblyAndCleanupDependenciesShuttingDown(BuildResultCompiledAssemblyBase compiledResult) { if (compiledResult == null) return; if (compiledResult != null && compiledResult.ResultAssembly != null && !compiledResult.UsesExistingAssembly) { string assemblyName = compiledResult.ResultAssembly.GetName().Name; lock (_dependentAssemblies) { RemoveAssemblyAndCleanupDependenciesNoLock(assemblyName); } } }
internal override void GetPreservedAttributes(PreservationFileReader pfr) { base.GetPreservedAttributes(pfr); this.ResultAssembly = BuildResultCompiledAssemblyBase.GetPreservedAssembly(pfr); }