[Canonical page](<https://docs.dhtmlx.com/planning-engine/net/api/core/evaluate/execution/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# Execution

How [`Project.EvaluateWith`](<https://docs.dhtmlx.com/planning-engine/net/api/project-evaluate.md#evaluatewith>) scores candidates: one after another, or on worker threads. Get a value from `Execution.Sequential` or `Execution.Parallel(...)`. Both modes return the same results.

## Declaration

```csharp
namespace Plen;

public readonly record struct Execution
```

`Execution` has no public constructor. `default(Execution)` is `Execution.Sequential`.

## Properties

| Property | Type | Description |
|---|---|---|
| `IsParallel` | `bool` | `true` for a value made by `Parallel`, `false` for `Sequential`. |
| `Threads` | `int?` | The thread count passed to `Parallel`. `null` means the processor count, and it's always `null` for `Sequential`. |

## Static members

### Sequential

```csharp
public static Execution Sequential { get; }
```

Scores one candidate after another. It's the default, and it's what [`Project.Evaluate`](<https://docs.dhtmlx.com/planning-engine/net/api/project-evaluate.md>) uses.

### Parallel

```csharp
public static Execution Parallel(int? threads = null)
```

Scores candidates on thread-pool workers, `threads` of them at most. Results and their order are the same as with `Sequential`. For memory use and error order, see [`Project.EvaluateWith`](<https://docs.dhtmlx.com/planning-engine/net/api/project-evaluate.md#evaluatewith>).

**Parameters**

| Name | Type | Description |
|---|---|---|
| `threads` | `int?` | Optional, default `null`. The maximum number of worker threads. `null` uses `Environment.ProcessorCount`. |

**Returns** - a parallel `Execution` with `IsParallel == true`.

**Errors** - throws `ArgumentOutOfRangeException` when `threads` is `0` or negative.

## Equality

`Execution` has value equality. `Execution.Parallel()` equals `Execution.Parallel(null)`, and `Execution.Parallel(4)` equals another `Execution.Parallel(4)`.

## Example

Score two candidates on up to four threads.

```csharp
using Plen;

var monday = Moment.FromYmdHm(2026, 8, 10, 8, 0) ?? throw new InvalidOperationException("invalid date");
var data = new ProjectData
{
    Tasks = [new TaskData("A") { StartDate = monday, Duration = 2.0 }],
    Resources = [new ResourceData { Id = "dev1" }, new ResourceData { Id = "dev2" }],
    Assignments = [new AssignmentData { Id = "aA", Task = "A", Resource = "dev1", Value = 1.0 }],
};
var project = new Project();
project.Solve(data, new SolveOptions());

var toDev2 = new SchedulingChanges();
toDev2.Assignments.Update.Add(new AssignmentUpdate("aA") { Resource = Patch<Id>.Of("dev2") });

Candidate[] candidates =
[
    new() { Id = "stay", Changes = new SchedulingChanges() },
    new() { Id = "dev2", Changes = toDev2 },
];

var execution = Execution.Parallel(4);
var result = project.EvaluateWith(candidates, new EvaluateOptions(), execution);

foreach (var candidate in result.Candidates)
    Console.WriteLine($"{candidate.Id}: cost {candidate.Cost}");
```

## Related

- [`Project.EvaluateWith`](<https://docs.dhtmlx.com/planning-engine/net/api/project-evaluate.md#evaluatewith>) - the call that takes an execution mode
- [`EvaluateOptions`](<https://docs.dhtmlx.com/planning-engine/net/api/core/evaluate/evaluate-options.md>) - the options passed alongside it
- [`EvaluateResult`](<https://docs.dhtmlx.com/planning-engine/net/api/core/evaluate/evaluate-result.md>) - the returned result, the same in both modes
- [Evaluating alternatives](<https://docs.dhtmlx.com/planning-engine/net/resources-and-assignment/evaluating-alternatives.md#parallel-evaluation>) - scoring candidates in parallel
- [Call from async code](<https://docs.dhtmlx.com/planning-engine/net/how-to/call-from-async-code.md>) - running engine calls off the request thread
