/// <summary> /// Constructor. /// </summary> public OutOfProcNode() { s_isOutOfProcNode = true; #if FEATURE_APPDOMAIN_UNHANDLED_EXCEPTION AppDomain.CurrentDomain.UnhandledException += ExceptionHandling.UnhandledExceptionHandler; #endif _debugCommunications = (Environment.GetEnvironmentVariable("MSBUILDDEBUGCOMM") == "1"); _receivedPackets = new ConcurrentQueue <INodePacket>(); _packetReceivedEvent = new AutoResetEvent(false); _shutdownEvent = new ManualResetEvent(false); _legacyThreadingData = new LegacyThreadingData(); _componentFactories = new BuildComponentFactoryCollection(this); _componentFactories.RegisterDefaultFactories(); _packetFactory = new NodePacketFactory(); _buildRequestEngine = (this as IBuildComponentHost).GetComponent(BuildComponentType.RequestEngine) as IBuildRequestEngine; _globalConfigCache = (this as IBuildComponentHost).GetComponent(BuildComponentType.ConfigCache) as IConfigCache; _taskHostNodeManager = (this as IBuildComponentHost).GetComponent(BuildComponentType.TaskHostNodeManager) as INodeManager; // Create a factory for the out-of-proc SDK resolver service which can pass our SendPacket delegate to be used for sending packets to the main node OutOfProcNodeSdkResolverServiceFactory sdkResolverServiceFactory = new OutOfProcNodeSdkResolverServiceFactory(SendPacket); ((IBuildComponentHost)this).RegisterFactory(BuildComponentType.SdkResolverService, sdkResolverServiceFactory.CreateInstance); _sdkResolverService = (this as IBuildComponentHost).GetComponent(BuildComponentType.SdkResolverService) as ISdkResolverService; if (s_projectRootElementCacheBase == null) { s_projectRootElementCacheBase = new ProjectRootElementCache(true /* automatically reload any changes from disk */); } _buildRequestEngine.OnEngineException += OnEngineException; _buildRequestEngine.OnNewConfigurationRequest += OnNewConfigurationRequest; _buildRequestEngine.OnRequestBlocked += OnNewRequest; _buildRequestEngine.OnRequestComplete += OnRequestComplete; (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.BuildRequest, BuildRequest.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.BuildRequestConfiguration, BuildRequestConfiguration.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.BuildRequestConfigurationResponse, BuildRequestConfigurationResponse.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.BuildRequestUnblocker, BuildRequestUnblocker.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.NodeConfiguration, NodeConfiguration.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.NodeBuildComplete, NodeBuildComplete.FactoryForDeserialization, this); (this as INodePacketFactory).RegisterPacketHandler(NodePacketType.ResolveSdkResponse, SdkResult.FactoryForDeserialization, _sdkResolverService as INodePacketHandler); }
private void CleanupCaches() { if (_componentFactories.GetComponent(BuildComponentType.ConfigCache) is IConfigCache configCache) { configCache.ClearConfigurations(); } if (_componentFactories.GetComponent(BuildComponentType.ResultsCache) is IResultsCache resultsCache) { resultsCache.ClearResults(); } if (Environment.GetEnvironmentVariable("MSBUILDCLEARXMLCACHEONCHILDNODES") == "1") { // Optionally clear out the cache. This has the advantage of releasing memory, // but the disadvantage of causing the next build to repeat the load and parse. // We'll experiment here and ship with the best default. s_projectRootElementCacheBase = null; } // Since we aren't going to be doing any more work, lets clean up all our memory usage. GC.Collect(); }