ProjectScheduler
Schedules a project plan by the critical-path method: works out every task's earliest and latest dates on a working calendar, its float, and the chain of tasks that decides when the plan finishes.
public static class ProjectScheduler
Remarks
What it is for
This is the engine behind the GanttChart, the PertChart and the
TaskBoard: each chart schedules its plan through it and draws the result, so the
three always agree. Call it yourself to work with the same dates without a chart – a report, an
export, a check on the server before a plan is saved.
How a plan is scheduled
- The outline is read: each task finds its parent, and every task gets an outline
number (
ScheduledTask.Wbs). - Each task's own dates are read: its duration in working days, its planned start
and any
ProjectTask.Constraint. - The links are checked, and any that cannot be honoured are reported and left out.
- The forward pass gives every task its earliest dates: as soon as its links, its summary, its planned start and the project's start allow.
- The backward pass gives every task its latest dates: as late as it can be without moving the project's finish.
- Float, the critical path and summaries' progress are worked out from the two.
Bad data is never fatal
A duplicate id, a link to a task that is not there, a loop of links: each is reported in
ProjectSchedule.Problems and left out, and everything else is still scheduled. The
scheduler does not throw for anything in the plan.
Working days
Durations and lags count working days on the calendar of ScheduleInput.WorkingDays
and ScheduleInput.Holidays, so a five-day task that starts on a Thursday finishes on
the following Wednesday. Dates have no time of day and no time zone, so a plan schedules to the same
dates on every machine.
Examples
A website plan of eight tasks, scheduled on a Monday-to-Friday week from Monday 2 November 2026. The comments give the dates the scheduler works out.
using System;
using System.Collections.Generic;
List<ProjectTask> tasks = new List<ProjectTask>
{
new ProjectTask("design", "Design"), // summary
new ProjectTask("brief", "Agree the brief", 3) { ParentId = "design" },
new ProjectTask("wire", "Wireframes", 5) { ParentId = "design" },
new ProjectTask("build", "Build"), // summary
new ProjectTask("front", "Front end", 10) { ParentId = "build" },
new ProjectTask("api", "Order API", 8) { ParentId = "build" },
new ProjectTask("test", "User testing", 4),
new ProjectTask("live", "Go live", 0) // milestone
};
List<TaskLink> links = new List<TaskLink>
{
new TaskLink("brief", "wire"),
new TaskLink("wire", "front"),
new TaskLink("wire", "api", TaskLinkType.StartToStart, 2),
new TaskLink("build", "test"), // after all of Build
new TaskLink("test", "live")
};
ProjectSchedule schedule = ProjectScheduler.Schedule(tasks, links, new DateTime(2026, 11, 2));
// brief Mon 2 Nov - Wed 4 Nov
// wire Thu 5 Nov - Wed 11 Nov
// api Mon 9 Nov - Wed 18 Nov (5 working days of float)
// front Thu 12 Nov - Wed 25 Nov
// test Thu 26 Nov - Tue 1 Dec
// live Tue 1 Dec
Console.WriteLine(schedule.ProjectFinish.ToString("yyyy-MM-dd")); // 2026-12-01
Console.WriteLine(string.Join(" > ", schedule.CriticalPath)); // brief > wire > front > test > live
Console.WriteLine(schedule.Find("api").TotalFloat); // 5
foreach (ScheduleProblem problem in schedule.Problems)
{
Console.WriteLine(problem.Message); // none for this plan
}See also
Members at a glance
| Methods | |
|---|---|
Code | Returns the two-letter code a planner writes a link type as, and the Gantt chart's Predecessors column uses. |
Schedule | Schedules a plan with full control of the calendar: the tasks, the links, the project's first day, the working week and the holidays. |
Schedule | Schedules a plan from its tasks and links on a Monday-to-Friday week with no holidays. |
Methods
Code static
Returns the two-letter code a planner writes a link type as, and the Gantt chart's Predecessors column uses.
Parameters
type- The link type.
Returns
FS, SS, FF or SF. A value that is not a
TaskLinkType gives FS.
Schedule static
Schedules a plan with full control of the calendar: the tasks, the links, the project's first day, the working week and the holidays.
Parameters
input- The plan and its calendar. Null schedules an empty plan.
Returns
The scheduled plan; never null. Anything in the input that could not be
used is in its ProjectSchedule.Problems.
Remarks
The input's collections are read once, during the call; the result does not follow later changes to them. Nothing in the input is changed.
Example
ProjectSchedule schedule = ProjectScheduler.Schedule(new ScheduleInput
{
Tasks = tasks,
Links = links,
ProjectStart = new DateTime(2026, 11, 2),
Holidays = new[] { new DateTime(2026, 12, 25), new DateTime(2026, 12, 28) }
});Schedule static
Schedules a plan from its tasks and links on a Monday-to-Friday week with no holidays.
Parameters
tasks- The tasks, in outline order within each parent. Null schedules an empty plan.
links- The links between them; null for none.
projectStart- The first day work can happen; null to take it from the tasks (the earliest planned start, then the earliest planned finish, and failing both, today).
Returns
The scheduled plan; never null.
Remarks
The same as Schedule() with no working days or holidays set.