public static IEnumerable <ProjectTaskTimephasedRule> GenerateTimephasedRules(this IEnumerable <ProjectTaskTimeSheet> timesheets) { ProjectTaskTimeSheet prevTimesheet = null; ProjectTaskTimephasedRule rule = null; foreach (var timesheet in timesheets.OrderBy(ts => ts.TaskId).ThenBy(ts => ts.StartTime)) { var populateRule = (prevTimesheet == null) || (prevTimesheet.TaskId != timesheet.TaskId) || (prevTimesheet.PlanWeightValue != timesheet.PlanWeightValue); if (populateRule) { if (rule != null) { yield return(rule); } rule = new ProjectTaskTimephasedRule(timesheet.ProjectId, timesheet.TaskId) { TimeRange = new TimeRange(timesheet.StartTime, TimeSpan.FromDays(1)), WeightValue = timesheet.PlanWeightValue }; } else { rule.TimeRange.End = timesheet.EndTime; rule.WeightValue += timesheet.PlanWeightValue; } prevTimesheet = timesheet; } if (rule != null) { yield return(rule); } }
public static IEnumerable <ProjectTaskTimephasedRule> GenerateTimephasedRulesAsParallel( this IEnumerable <ProjectTaskTimeSheet> timesheets) { var timesheetList = timesheets.ToList(); #if !SILVERLIGHT return (timesheets .Select(x => x.TaskId) .Distinct() .AsParallel() .AsOrdered() .SelectMany(taskId => { ProjectTaskTimeSheet prevTimesheet = null; ProjectTaskTimephasedRule rule = null; var rules = new List <ProjectTaskTimephasedRule>(); foreach (var timesheet in timesheetList.Where(x => x.TaskId == taskId)) { var populateRule = (prevTimesheet == null) || (prevTimesheet.PlanWeightValue != timesheet.PlanWeightValue); if (populateRule) { rule = new ProjectTaskTimephasedRule(timesheet.ProjectId, timesheet.TaskId) { TimeRange = new TimeRange(timesheet.StartTime, TimeSpan.FromDays(1)), WeightValue = timesheet.PlanWeightValue }; rules.Add(rule); } else { rule.TimeRange.End = timesheet.EndTime; rule.WeightValue += timesheet.PlanWeightValue; } prevTimesheet = timesheet; } return rules; })); #else var rules = new List <ProjectTaskTimephasedRule>(); object _syncLock = new object(); Parallel.ForEach(timesheetList.Select(x => x.TaskId).Distinct(), () => new List <ProjectTaskTimephasedRule>(), (taskId, loop, localRules) => { ProjectTaskTimeSheet prevTimesheet = null; ProjectTaskTimephasedRule rule = null; foreach (var timesheet in timesheetList.Where(x => x.TaskId == taskId)) { var populateRule = (prevTimesheet == null) || (prevTimesheet.PlanWeightValue != timesheet.PlanWeightValue); if (populateRule) { rule = new ProjectTaskTimephasedRule(timesheet.ProjectId, timesheet.TaskId) { TimeRange = new TimeRange(timesheet.StartTime, TimeSpan.FromDays(1)), WeightValue = timesheet.PlanWeightValue }; localRules.Add(rule); } else { rule.TimeRange.End = timesheet.EndTime; rule.WeightValue += timesheet.PlanWeightValue; } prevTimesheet = timesheet; } return(localRules); }, localRules => { lock (_syncLock) rules.AddRange(localRules); }); return(rules.OrderBy(r => r.TaskId).ThenBy(r => r.TimeRange.Start)); #endif }