Skip to main content

CPU Hot Paths and Server-Side UI Work

The dashboard refresh is fixed: 476 ms → 113 ms, medians of three warm runs, against a noise floor of 13 %.

The fix is the one the lesson asks for — a DashboardSnapshot of display-ready values built once in the service, assigned to controls that already exist — applied where the profiler said the time actually was. See BeforeAfter.md and SnapshotDesign.md.

Run it​

cd "LearnWisej-Samples/Performance and Profiling Course/Module 3/WisejPerfLab"
dotnet run -c Release -f net10.0 --urls http://localhost:5803

To see the before and after side by side, run Module 2 on 5802 at the same time and click Refresh in both.

What to click​

ActionWhat you should see
Warm up (discarded run), then Dashboard → RefreshRefresh 109 ms — within the 250 ms budget 4 queries as of 11:31:45
the PERF log for that runstage Refresh / snapshot (4 aggregate queries, formatted once) 109 ms, stage Refresh / assign 0 ms — and no calls TicketFormatter.FormatRow line, because it is never called
Run the three scenarios ×3median Dashboard/Refresh = 113 ms — within the 250 ms budget, spread 13 %
Click Refresh twice quicklythe second click is dropped: a refresh is already running — the second click was dropped
Break the database → Refreshthe button comes back, the banner explains, the KPIs keep their last good values, and the PERF end record is still written with failed=DatabaseUnavailableException
Compare the KPI numbers with Module 2identical: 11,907 open, ~21,64x overdue, 90.5 d average age

The other two scenarios are untouched and still over budget — Tickets/Search 414 ms, tree expand 158 ms. They are Modules 4, 5 and 6.

One thing here belongs to Module 4​

This folder also carries Diagnostics/MemoryProbe.cs, the detail-form counters and the three buttons Memory snapshot A / Open and close the detail form ×50 / Snapshot B and compare — with the unfixed detail form. They are here so the before reading for Module 4 can be taken on the code as it stood: B - A: heap +76.0 MB subscribers +50. Module 4 fixes the form and the same three buttons report +1.1 MB subscribers 0.

What changed since Module 2​

Models/DashboardSnapshot.cs new — OpenTicketsText, OverdueTicketsText, AverageAgeText, ChartRows, GeneratedAt
Services/DashboardService.cs + GetSnapshot(): 4 aggregate queries, formatted once, no entity returned
LoadAllTickets() kept but no longer called by anything
Services/TicketFormatter.cs status/priority labels are now a static lookup, not a per-call string.Format
+ FormatDay() for the chart axis
Pages/DashboardPage.cs rewritten: KPI cards built once in the constructor, values assigned,
RebuildKpiPanel deleted, _refreshing guard added

Nothing else moved. ScenarioProbe, the budget, the PERF log and the scenario definitions are identical to Module 2, so the before/after table compares the same measurement.