public void StopAll() { if (Count == 0) { return; } //Collect all runners and take ownership List <ConsoleRunner> runners = new List <ConsoleRunner>(); for (int i = 0; i < Count; i++) { ConsoleRunner runner = this[i].Runner; if (runner == null) { continue; } runners.Add(runner); this[i].Runner = null; } if (runners.Count == 0) { return; } DateTime limit = DateTime.UtcNow.AddSeconds(30); int stoppedNormal = 0; int stoppedError = 0; for (int phase = 0; phase < 3; phase++) { bool atLeastOneWantedToWait = false; for (int i = 0; i < runners.Count; i++) { ConsoleRunner runner = runners[i]; try { //logger.Log("StopAll -- phase={0} runner={1}.", phase, runner.Name); bool waitNeeded = false; switch (phase) { case 0: waitNeeded = runner.Stop_Initiate(); break; case 1: waitNeeded = runner.Stop_CtrlC(); break; case 2: waitNeeded = runner.Stop_Kill(); break; } if (waitNeeded) { atLeastOneWantedToWait = true; } } catch (Exception e) { logger.Log("StopAll failed in phase {0} for runner {1}.", phase, runner.Name); logger.Log(e); } } //logger.Log("StopAll -- atLeastOneWantedToWait={0}.", atLeastOneWantedToWait); if (!atLeastOneWantedToWait) { continue; } if (waitForAllExit(runners, limit)) { break; } limit = DateTime.UtcNow.AddSeconds(30); } //Check if there were any errors for (int i = 0; i < runners.Count; i++) { ConsoleRunner runner = runners[i]; runner.CheckStoppedAndDispose(); if (runner.ErrorsDuringExit) { stoppedError++; } else { stoppedNormal++; } } if (stoppedError == 0) { logger.Log(_LogType.ltInfo, "All processes ({0}) stopped correctly...", stoppedNormal); return; } logger.Log(_LogType.ltError, "Stopped {0} processes. {1} of them stopped correctly, {2} failed.", stoppedNormal + stoppedError, stoppedNormal, stoppedError); }