[Canonical page](<https://docs.dhtmlx.com/planning-engine/net/how-to/load-all-task-dates/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# Load all task dates

Get the start, end and duration of every scheduled task from one solve, for example to fill your UI when a project first opens.

By default, `Updates` in a [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/schedule-result.md>) is sparse: it lists only the tasks that moved. Set [`SolveOptions.IncludeUnchanged`](<https://docs.dhtmlx.com/planning-engine/net/api/core/project/solve-options.md#includeunchanged>) and the same solve also reports the tasks that didn't move. You don't need a separate call.

## Steps

1. Create the solve options with `IncludeUnchanged` set to `true`:

   ```csharp
   var options = new SolveOptions { IncludeUnchanged = true };
   ```

2. Pass the options to the solve that loads the data. Use [`Project.Solve`](<https://docs.dhtmlx.com/planning-engine/net/api/project-solve.md>) with your [`ProjectData`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/project-data.md>) for a long-lived project, or [`Engine.Schedule`](<https://docs.dhtmlx.com/planning-engine/net/api/engine-schedule.md>) for a one-shot job.

3. Read every entry of [`result.Updates`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/schedule-result.md#updates>). Each [`Mutation`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/mutation.md>) has `StartDate`, `EndDate` and `Duration` set.

The full example below schedules three tasks. `review` doesn't move, but it's still reported:

```csharp
using Plen;

var jan1 = Moment.FromYmdHm(2026, 1, 1, 0, 0) ?? throw new InvalidOperationException("invalid date");
var jan5 = Moment.FromYmdHm(2026, 1, 5, 0, 0) ?? throw new InvalidOperationException("invalid date");

var data = new ProjectData
{
    Tasks =
    [
        new TaskData("design") { StartDate = jan1, Duration = 2.0 },
        new TaskData("build") { StartDate = jan1, Duration = 1.0 },
        new TaskData("review") { StartDate = jan5, Duration = 1.0 },
    ],
    Links = [new LinkData { Id = "design-build", Source = "design", Target = "build" }],
};
// 24/7 time keeps the example dates easy to check.
data.Config.UseCalendars = false;

var options = new SolveOptions { IncludeUnchanged = true };

var project = new Project();
var result = project.Solve(data, options);

foreach (var m in result.Updates)
{
    Console.WriteLine($"{m.Id} {m.StartDate}..{m.EndDate} {m.Duration}");
}
```

## Get the full list from an already solved project

To reload every date later, call [`Solve(null, …)`](<https://docs.dhtmlx.com/planning-engine/net/api/project-solve.md>) with the same options. On a solved project with no pending edits, the call doesn't replan or change the accepted state, and [`BaselineId`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/schedule-result.md#baselineid>) stays the same:

```csharp
var allDates = project.Solve(null, options);
```

Switch back to sparse results for the edits that follow. A default `SolveOptions` returns only what changed:

```csharp
var next = project.Solve(null, new SolveOptions());
```

The result cache uses the whole [`SolveOptions`](<https://docs.dhtmlx.com/planning-engine/net/api/core/project/solve-options.md>) as its key, compared by value. An `IncludeUnchanged` call never gets a cached sparse result, and a sparse call never gets a cached full one. Repeating a call with equal options returns the same [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/schedule-result.md>) object, so treat it as read-only, or call `DeepClone()` before you change it.

## What is and isn't reported

- The result includes every scheduled task: leaf tasks, summaries and milestones. Check [`Mutation.Kind`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/mutation.md#mutationkind>) to tell them apart.
- Tasks with `Unscheduled = true` are never reported.
- `LevelingDelay` and `Pauses` are always `null`, because a solve doesn't change them.
- [`BaselineId`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/schedule-result.md#baselineid>) follows real changes only. Asking for unchanged tasks doesn't create a new baseline.
- With [`Subtree`](<https://docs.dhtmlx.com/planning-engine/net/how-to/reschedule-a-branch.md>), the result holds every task in the subtree, including the subtree tasks' ancestors. Tasks outside the subtree appear only when a sparse subtree solve would report them too, because they changed or were edited.
- On a project with a dependency cycle, nothing is scheduled. The result still lists every scheduled task, in model order, with its dates and duration as stored. `Subtree` is ignored, and no entry has a [`Reason`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/reason.md>), even with [`Reasons = true`](<https://docs.dhtmlx.com/planning-engine/net/api/core/project/solve-options.md#reasons>).
- [`Project.Preview`](<https://docs.dhtmlx.com/planning-engine/net/api/project-preview.md>) and [`Project.Level`](<https://docs.dhtmlx.com/planning-engine/net/api/project-level.md>) always return sparse updates.

## Result

The example prints one line per task, including `review`, which didn't move (the lines may come in a different order):

```text
design 2026-01-01 00:00..2026-01-03 00:00 2
build 2026-01-03 00:00..2026-01-04 00:00 1
review 2026-01-05 00:00..2026-01-06 00:00 1
```

Without [`IncludeUnchanged`](<https://docs.dhtmlx.com/planning-engine/net/api/core/project/solve-options.md#includeunchanged>), the same solve reports only `build`.

See [Reading results](<https://docs.dhtmlx.com/planning-engine/net/scheduling/reading-results.md>) for how to write the dates back into your model.
