A Blazor WebAssembly demo showcasing a lightweight hierarchical task timing & progress reporting utility. It simulates “making breakfast” by orchestrating parallel and nested tasks (coffee, toast, eggs, bacon, juice) while demonstrating:
- Nested task timing (parent / child relationships)
- Weighted progress aggregation (percent of total work)
- Start / complete / cancel / error / expiration events
- Max duration vs expiration semantics
- Cooperative cancellation via CancellationTokenSource
- Parallel slice processing (toast & bacon) using Parallel.ForEachAsync
- UI status reporting via a TaskReport component
Page | Route | Purpose |
---|---|---|
Breakfast.razor | / | Full orchestration demo with cancellation + nested timers |
BasicTimer.razor | /timer | Minimal example with three weighted tasks |
Represents a unit of work (primary or sub-task). Features:
- Start(), Complete(), Cancel(), Stop(), Restart()
- Optional: PercentOfWorkForParentTask
- MaxDurationInSeconds → triggers "Error" (burnt)
- ExpirationInSeconds → triggers "Expired" (cold/stale)
- ParentTask + automatic aggregation of progress
- Event hooks (e.g., OnCancelEvent)
- Elapsed time tracking (Stopwatch + timers)
(Not shown here, but inferred)
- Registers TaskTimer instances
- Emits status lines (Started / Completed / Error / Expired / Cancelled / Info / Alert)
- Provides SimulateDelay(...) helper (wrapping Task.Delay + cancellation)
Primary task: “Breakfast” Subtasks executed concurrently:
- MakeCoffee (with max + expiration timers)
- ToastBread (per-slice parallelization + optional butter/jam subtasks)
- MakeEggs (pan warm + fry eggs, includes max + expiration)
- FryBacon (per-slice timers with burn/cold thresholds)
- PourJuice (simple timed task)
Cancellation triggers cleanup messages (e.g., turning off pan / coffee pot).
Simplifies usage to three sequential weighted tasks (20% / 50% / 30%) to illustrate progress composition.
## Cancellation
Each sub-task can attach OnCancelEvent to perform contextual cleanup messaging.
Parallel.ForEachAsync is used for toast & bacon slices. In WebAssembly:
- Without multithreading enabled, this may run effectively sequentially.
- To enable threading, ensure:
- Property true in the project file
- Hosted in a secure cross-origin-isolated context (COOP/COEP headers) If threading is not enabled, logic still functions—just without true parallel speedup.
Prerequisites:
- .NET 8 SDK
- Modern browser (Chromium, Firefox, Edge)
Goal | Approach |
---|---|
Add new task type | RegisterSubTask + Start/Complete |
Add retry logic | Wrap SimulateDelay / work block with Polly or manual loop |
Persist history | Inject a state service; cache TaskEventArgs sequence |
UI customization | Modify TaskReport rendering (e.g., color-code statuses) |
Real workloads | Replace SimulateDelay with I/O or compute operations |
- MaxDurationInSeconds → Task ran too long (treated as failure condition / “burnt”)
- ExpirationInSeconds → Task completed (or not) but exceeded freshness window (“cold”)
TimerDemo illustrates structured, cancellable, hierarchical task timing inside a Blazor WebAssembly UI, providing an educational pattern for progress reporting, task composition, and lifecycle signaling.
Happy timing!