private void EnterMainLoop() { try { Logger.Add("STARTUP -- Entering main loop..."); while (!_shutDownRequested) { if (_processStatusListeners.Any(x => x.Value)) { try { Configuration configuration = Configuration.Read(); if (configuration.Applications.Count > 0 && configuration.Groups.Sum(group => group.Applications.Count) > 0) { List <string> runningProcesses = ProcessHandler.GetProcesses(); var processesStatusList = configuration.Groups .SelectMany(group => configuration.Applications .Where(application => group.Applications.Contains(application.ID)) .Select(application => new { Group = group, Application = application, Path = Path.Combine(group.Path, application.RelativePath.TrimStart('\\')) })) .Select(x => new { x.Group, x.Application, Status = new ProcessStatus(x.Group.ID, x.Application.ID, runningProcesses.Any(runningProcess => runningProcess.Equals(x.Path, StringComparison.CurrentCultureIgnoreCase)) ? ProcessStatusValue.Running : ProcessStatusValue.Stopped) }) .ToList(); List <ProcessStatus> changedProcessStatuses; lock (_processStatuses) { changedProcessStatuses = processesStatusList .Where(x => !_processStatuses.ContainsKey(x.Group.ID) || !_processStatuses[x.Group.ID].ContainsKey(x.Application.ID) || _processStatuses[x.Group.ID][x.Application.ID].Value != x.Status.Value) .Select(x => x.Status) .ToList(); _processStatuses = processesStatusList .GroupBy(x => x.Group.ID) .ToDictionary(x => x.Key, x => x.ToDictionary(y => y.Application.ID, y => y.Status)); } if (changedProcessStatuses.Count > 0) { RaiseProcessStatusesChangedEvent(changedProcessStatuses); } } } catch (Exception ex) { Logger.Add("An unexpected error occurred in main loop", ex); } } Thread.Sleep(Settings.Service.Read <int>("StatusUpdateInterval")); } Logger.Add("SHUTDOWN -- Exiting main loop..."); } catch (Exception ex) { Logger.Add("Fatal exception in main loop, dying....", ex); } }