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 databaseRefreshthe 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.