static Task ReleaseProjectBuilderNoLock(RemoteBuildEngine engine) { if (--engine.ReferenceCount != 0) { return(Task.CompletedTask); } if (engine.IsShuttingDown) { // If the engine is being shut down, dispose it now. builders.Remove(engine); engine.DisposeGracefully(); } else { // Wait a bit before disposing the engine. We may need to use it again. engine.ScheduleForDisposal(EngineDisposalDelay).ContinueWith(async t => { using (await buildersLock.EnterAsync().ConfigureAwait(false)) { // If this is the last standing build engine for the solution, don't dispose it. // In this way there will always be at least one build engine for each solution, // until explicitly unloaded. if (!builders.GetAllBuilders().Where(b => !b.IsShuttingDown && b != engine && b.SolutionFile == engine.SolutionFile).Any()) { return; } // If after the wait there are still 0 references, dispose the builder if (engine.ReferenceCount == 0) { builders.Remove(engine); engine.DisposeGracefully(); } } }, TaskContinuationOptions.NotOnCanceled); } return(Task.CompletedTask); }
static void ShutdownBuilderNoLock(RemoteBuildEngine engine) { // Signal all project builder of the engine to stop engine.Shutdown(); // If there are no references it means the engine is not being used, so it can be disposed now. // Otherwise it will be disposed when all references are released if (engine.ReferenceCount == 0) { engine.CancelScheduledDisposal(); builders.Remove(engine); engine.DisposeGracefully(); } }