//Main Loop ======================= Main Loop: async Task runMainLoop(ConfigureUtil config) { var poolCopy = new List <Actor_SansType>(); void safeLog(string location, Exception ex) { try { runtimeLog.Error(location, "Main Loop", ex); } catch { } } runtimeLog.Info("DirectorLoopStarted"); bool readkeyFailed = false; while (Running) { try { try { if (!readkeyFailed && Environment.UserInteractive) { if (Console.KeyAvailable) { var key = Console.ReadKey(true).Key; if (key == ConsoleKey.Q || key == ConsoleKey.Escape) { this.Dispose(); await Task.Delay(5000); //Simulate the time we normally get for shutdown. } } } } catch (Exception ex) { readkeyFailed = true; safeLog("User Interactive Check", ex); } try { poolCopy.Clear(); lock (lockProcessPool) { poolCopy.AddRange(processPool); } } catch (Exception ex) { safeLog("Process Pool Copy", ex); } try { var shouldRemove = poolCopy.Where(x => x.ShouldBeRemovedFromPool).ToList(); if (shouldRemove.Count > 0) { lock (lockProcessPool) { processPool.RemoveAll(x => shouldRemove.Contains(x)); poolCopy.Clear(); poolCopy.AddRange(processPool); } } } catch (Exception ex) { safeLog("Process Pool Pruning", ex); } List <ActorDisposeHandle> handles = null; lock (lockDisposeHandles) { handles = disposeHandles; } try { var remainingHandles = new List <ActorDisposeHandle>(); if (handles != null) { foreach (var handle in handles) { if (handle.MustDispose) { #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed handle.DisposeProcess(getCurrentDispatchData); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed } else { remainingHandles.Add(handle); } } lock (lockDisposeHandles) { if (disposeHandles != null) { disposeHandles = remainingHandles; } } } } catch (Exception ex) { safeLog("Dispose Processes", ex); } try { List <object> newDependencies = null; lock (lockNewlyRegisteredDependencies) { if (newlyRegisteredDependencies.Count > 0) { newDependencies = newlyRegisteredDependencies.ToList(); newlyRegisteredDependencies.Clear(); } } if (newDependencies != null) { foreach (var newDependency in newDependencies) { try { if (newDependency is Actor_SansType) { var process = newDependency as Actor_SansType; #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed process.Init(getCurrentDispatchData).ContinueWith(async task => { #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed if (task.Status == TaskStatus.RanToCompletion) { if (task.Result != null) { var handle = task.Result; var mustDisposeNow = false; lock (lockDisposeHandles) { if (disposeHandles != null) { lock (lockProcessPool) { processPool.Add(process); } disposeHandles.Add(handle); } else { //Means that the whole application has been disposed. mustDisposeNow = true; } } if (mustDisposeNow) { await handle.DisposeProcess(getCurrentDispatchData); } } } }); } else if (newDependency is IOnInit) { #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed (newDependency as IOnInit).OnInit(new ActorUtil(newDependency as Actor_SansType, this.Clock)); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed } } catch (Exception ex) { safeLog("Initializing Dependency", ex); } } } } catch (Exception ex) { safeLog("Initializing Dependencies", ex); } try { foreach (var process in poolCopy) { try { if (process.ShouldBeRunNow(process.IgnoreSimulatedTime? DateTimeOffset.Now : Clock.Now)) { #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed process.Run(getCurrentDispatchData); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed } } catch (Exception ex) { safeLog("Running Process", ex); } } } catch (Exception ex) { safeLog("Running All Processes", ex); } await Task.Delay(new TimeSpan(0, 0, 0, 0, config.RunLoopIntervalMs)); } catch (Exception ex) { safeLog("main while", ex); } } }