WJb Docs - Intermediate
Learn workflows, persistence, scheduling, and production-ready patterns.
π Start Here
π§© Mental Model
π Building Workflows
π₯ Failures & Control
π Observation & Debugging
π Practical Patterns
β Working Examples
β‘οΈ Whatβs Next
π Progress
Long-running actions can report progress so that clients and monitoring tools can show feedback.
Updating Progress
From inside an action you can report progress:
public override async Task<IActionResult> ExecuteAsync(
ImportInput input, CancellationToken ct)
{
for (int i = 0; i <= 100; i += 10)
{
ct.ThrowIfCancellationRequested();
// do a chunk of work...
await UpdateProgressAsync(i, $"Processed {i}%");
await Task.Delay(500, ct); // simulate work
}
return await CompleteAsync();
}
The exact helper name may be UpdateProgress or available through the context β the idea is the same:
- Current percentage (0β100)
- Optional message
What Gets Stored
Progress information is attached to the job and typically includes:
- Progress value (0β100)
- Status message
- Last update timestamp
Reading Progress
var job = await store.GetJobAsync(jobId);
Console.WriteLine($"{job.Progress}% - {job.Message}");
Or via a monitoring UI (for example WJb.UI.Blazor).
Best Practices
- Report progress at meaningful milestones, not on every tiny step
- Keep messages short and useful
- Always respect the
CancellationToken - Do not report progress after the action has completed or failed
- Prefer percentage values that move forward (avoid going backwards)
Example with Real Work
public override async Task<IActionResult> ExecuteAsync(
ProcessFilesInput input, CancellationToken ct)
{
var files = input.Files;
int total = files.Count;
for (int i = 0; i < total; i++)
{
ct.ThrowIfCancellationRequested();
await ProcessFileAsync(files[i], ct);
int percent = (i + 1) * 100 / total;
await UpdateProgressAsync(percent, $"Processed {i + 1} of {total}");
}
return await CompleteAsync();
}
Key Point
Progress is optional but very useful for long-running jobs.
It turns an opaque background task into something observable and user-friendly.