Project.Solve#
Schedules a Project and accepts the scheduled dates as its baseline. Pass a ProjectData to load a project, or null to reschedule after Apply. The other read-only calls (Preview, Evaluate, SuggestAssignments and the rest) need a solved project.
For a one-shot run that keeps no state, use Engine.Schedule.
Signature#
public ScheduleResult Solve(ProjectData? data, SolveOptions options)
Synchronous and CPU-only. Changes the project's state.
Parameters#
| Name | Type | Description |
|---|---|---|
data |
ProjectData? |
Replacement data, or null to schedule the current state |
options |
SolveOptions |
Subtree, analytics and reporting switches |
Behavior#
- A non-null
datais deep-copied, validated, installed, scheduled and accepted. The previous data is discarded. Later changes to the caller'sProjectDatadon't reach the project.ProjectOptions.Validationdecides whether invalid data is rejected or repaired. nullschedules the current state when it has unsolved edits. When the project is already solved with equaloptions, it returns the same cached result object without scheduling again. The cache key is the wholeSolveOptionsvalue, compared by value.
Tasks touched by successful Apply calls since the last solve appear in Updates as direct updates, even when the planner leaves them where the edit put them. A cyclic project returns unchanged dates and keeps those tasks pending.
The result's BaselineId names the accepted baseline. It changes only when the data or the dates change, so solving an unchanged state keeps it.
Returns#
The ScheduleResult. The project keeps the result as its baseline and shares it with clones. A later call can return the same object. Treat it as read-only, or call DeepClone() before modifying it.
Errors#
| Error | When |
|---|---|
InputException |
data fails validation, or options.Subtree names an unknown or unscheduled task (Path == "subtree.task"). The previous state and cached result are kept. |
ProjectException NeedsResync |
data is null after an Apply rejected an operation and no Solve(data, …) followed |
ArgumentNullException |
options is null |
Example#
Load a project, commit an edit and reschedule it.
using Plen;
var monday = Moment.FromYmdHm(2026, 8, 10, 8, 0) ?? throw new InvalidOperationException("invalid date");
var data = new ProjectData
{
Tasks = [new TaskData(1) { StartDate = monday, Duration = 2.0 }],
};
var options = new SolveOptions();
var project = new Project();
var loaded = project.Solve(data, options);
// Nothing changed: the cached result comes back with the same baseline.
var again = project.Solve(null, options);
Console.WriteLine(again.BaselineId == loaded.BaselineId); // True
var changes = new SchedulingChanges();
changes.Tasks.Update.Add(new TaskUpdate(1) { Duration = 3.0 });
project.Apply(changes);
var result = project.Solve(null, options);
foreach (var update in result.Updates)
Console.WriteLine($"task {update.Id}: {update.StartDate} .. {update.EndDate}"); // task 1: 2026-08-10 08:00 .. 2026-08-13 08:00
Related#
SolveOptions- the optionsScheduleResult- the returned resultEngine.Schedule- the one-shot call that keeps no state- Scheduling a project - loading, caching and solve options
- Editing a project - committing edits and rescheduling