protected bool ConfirmShutdown() { if (!this.IsShuttingDown) { return(false); } Contract.Assert(this.InEventLoop, "must be invoked from an event loop"); this.CancelScheduledTasks(); if (this.gracefulShutdownStartTime == PreciseTimeSpan.Zero) { this.gracefulShutdownStartTime = PreciseTimeSpan.FromStart; } if (this.RunAllTasks() || this.RunShutdownHooks()) { if (this.IsShutdown) { // Executor shut down - no new tasks anymore. return(true); } // There were tasks in the queue. Wait a little bit more until no tasks are queued for the quiet period. this.WakeUp(true); return(false); } PreciseTimeSpan nanoTime = PreciseTimeSpan.FromStart; if (this.IsShutdown || (nanoTime - this.gracefulShutdownStartTime > this.gracefulShutdownTimeout)) { return(true); } if (nanoTime - this.lastExecutionTime <= this.gracefulShutdownQuietPeriod) { // Check if any tasks were added to the queue every 100ms. // TODO: Change the behavior of takeTask() so that it returns on timeout. // todo: ??? this.WakeUp(true); Thread.Sleep(100); return(false); } // No tasks were added for last quiet period - hopefully safe to shut down. // (Hopefully because we really cannot make a guarantee that there will be no execute() calls by a user.) return(true); }