public DerivedProgressionManager(IObservableList <IProgressionViewer> subProgs, ILoggerFactory loggerFactory) { this.logger = loggerFactory.CreateLogger <DerivedProgressionManager>(); subProgs .Connect() .ToCollection() .Select(progs => progs.Select(prog => prog.WhenAnyValue( vm => vm.Title, vm => vm.State, vm => vm.Target, vm => vm.Current, vm => vm.Details, vm => vm.Weight, ProgressionSnapshot.Factory))) .Select(Observable.CombineLatest) .Switch() .Subscribe(progs => { this.State = JobStateHelper.MergeStates(progs.Select(prog => prog.State)); Target = progs.Sum(prog => prog.Weight) * Resolution; Current = (int)progs.Sum(prog => (decimal)prog.Current / (decimal)prog.Target * Weight * Resolution); var newDetails = progs.FirstOrDefault(x => x.State == JobState.InProgress).Details; if (State.IsIn(JobState.ToDo, JobState.Done)) { newDetails = string.Empty; } if (State == JobState.Failed) { newDetails = $"Job Failed.{Environment.NewLine + progs.FirstOrDefault(x => x.State == JobState.Failed).Details}"; logger.LogError("job failed: {0}", newDetails); } Details = newDetails; logger.LogTrace("extra info:" + subProgs.Count + Environment.NewLine + string.Join(Environment.NewLine, progs.Select(prog => $" {prog.Title} | {prog.State} | {prog.Current}/{prog.Target} : {prog.Details}")) ); logger.LogTrace("updating progress - {0}subs: {1}/{2} ({3}): {4}", progs.Count(), Current, Target, State, Details); }); }