/// <summary> /// Shutsdown the C-DEngine and all plugins /// Applications can override this function to add custom shutdown code /// </summary> /// <param name="ForceExit">If True and the C-DEngine will Stop or restart the hosting application. If it is hosted in IIS, the Application Pool hosting the app will be Stopped or Restarted depending on the next parameter</param> /// <param name="waitIfPending">Waits in case The shutdown is already initiated</param> public virtual void Shutdown(bool ForceExit, bool waitIfPending = false) { if (!waitIfPending) { if (!TheBaseAssets.MasterSwitch || TheCommonUtils.cdeIsLocked(ShutdownLock)) { return; //Make sure we dont do this twice } } lock (ShutdownLock) { if (TheBaseAssets.MasterSwitch) { if (TheBaseAssets.IsStarting) { TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, "Shutdown was requested, but startup has not finished. Waiting for startup to finish.", eMsgLevel.l3_ImportantMessage)); // Ensure we wait for user manager so CUOFS first-run-only settings are applied var sw = System.Diagnostics.Stopwatch.StartNew(); while (TheBaseAssets.IsStarting && sw.ElapsedMilliseconds < 60000) { Thread.Sleep(100); } if (TheBaseAssets.IsStarting) { TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, "Shutdown was requested, but startup has not finished after wait time (60 seconds). Shutting down regardless. Some first-run-only settings may not have been applied.", eMsgLevel.l1_Error)); } } if (TheBaseAssets.MyServiceHostInfo.PreShutDownDelay > 0) { var tcsPreHandlers = new TaskCompletionSource <bool>(); TheCommonUtils.cdeRunAsync("PreShutdownHandlers", true, (o) => { TheCDEngines.MyContentEngine?.FireEvent(eEngineEvents.PreShutdown, null, TheBaseAssets.MyServiceHostInfo.PreShutDownDelay, false); tcsPreHandlers.TrySetResult(true); }); tcsPreHandlers.Task.Wait(TheBaseAssets.MyServiceHostInfo.PreShutDownDelay); } while (Interlocked.Read(ref TheBaseAssets.DelayShutDownCount) > 0) { TheCommonUtils.SleepOneEye(100, 100); } TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, TheBaseAssets.MyServiceHostInfo.ApplicationTitle + " Initiating shutdown at : " + TheCommonUtils.GetDateTimeString(DateTimeOffset.Now), eMsgLevel.l6_Debug)); TheBaseAssets.MasterSwitch = false; TheBaseAssets.ForceShutdown = ForceExit; TheCDEngines.StopAllEngines(); TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, TheBaseAssets.MyServiceHostInfo.ApplicationTitle + " Shutdown: Engines stopped at: " + TheCommonUtils.GetDateTimeString(DateTimeOffset.Now), eMsgLevel.l6_Debug)); TheCommCore.StopCommunication(); TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, TheBaseAssets.MyServiceHostInfo.ApplicationTitle + " Shutdown: Communications stopped at: " + TheCommonUtils.GetDateTimeString(DateTimeOffset.Now), eMsgLevel.l6_Debug)); if (MyCommonDisco != null) { MyCommonDisco.ShutdownDiscoService(); TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, TheBaseAssets.MyServiceHostInfo.ApplicationTitle + " Shutdown: Discovery Service stopped at: " + TheCommonUtils.GetDateTimeString(DateTimeOffset.Now), eMsgLevel.l6_Debug)); } if (TheBaseAssets.MySYSLOG != null) { string iis = ""; switch (TheBaseAssets.MyServiceHostInfo.cdeHostingType) { case cdeHostType.IIS: iis = " (Hosted in IIS)"; break; case cdeHostType.ASPCore: iis = " (Hosted in ASP.NET Core)"; break; } TheBaseAssets.MySYSLOG.WriteToLog(3, new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, TheBaseAssets.MyServiceHostInfo.ApplicationTitle + iis + " Stopped at : " + TheCommonUtils.GetDateTimeString(DateTimeOffset.Now), eMsgLevel.l4_Message)); //Log Entry that service has been started TheBaseAssets.MySYSLOG.Shutdown(); } } } }