Real-Time Systems, Background Pipelines, Notifications & Imports
The Import Center (ImportCenterPage) starts imports it does not run,
a job queue executes them on a thread with no session, a job status store records every milestone, a
progress observer pushes to the browser with Application.StartTask + Application.Update at a bounded
rate, a notification panel delivers the result to whoever is there when it lands, and the
JobDetailPanel shows the history and the per-row report.
The failure path is the one that matters: close the session and the job keeps running. Close the browser tab mid-import and open the app again: the new session finds the same job in the store, selects it and carries on showing its progress.
Nothing here is deployed anywhere and nothing touches a network: a plain Wisej.NET 4 project on this machine, with in-memory fakes for the files, the work-order table, the queue and the notification store.
Run it
cd "LearnWisej-Samples/Enterprise Wisej.NET Course\Module 6\EnterpriseOps"
dotnet run -f net10.0 --urls http://localhost:5206
Then open http://localhost:5206. (Visual Studio: open EnterpriseOps.slnx, press F5 — the port is in
Properties/launchSettings.json.)
Requirements: .NET 10 SDK and the Wisej-4 4.1.0 NuGet package.
dotnet build -nologo -v q passes with 0 warnings and 0 errors on both target frameworks.
The session is seeded as ana.ops (Manager) of tenant contoso (Program.Main).
What to click
| Control | What you should see |
|---|---|
file combo + + New import… (header) | contoso_q2.csv → the job appears as Queued, the worker picks it up, prgJob steps through 10 batches (~9 s) and it ends Completed w/ errors · ✓ 998 imported (938 created, 60 updated) · ↻ 12 retried in 18 attempts · ✕ 2 terminal. contoso_pilot.csv → 300 clean rows, ends Completed. Importing the same file again reports 0 created, 998 updated (idempotent upsert by ExternalRef) |
| Cancel job (header) | click during batch 4: the status bar reads cancelling — finishing the current batch, the bar advances to the end of that batch, then Canceled after batch 4 of 10 · 400 rows imported, none half-written. |
| close the tab, open the app again | the recovery path: start contoso_q2.csv, close the tab at ~40 %, reopen http://localhost:5206. The new session selects the running job, toasts While you were away: IMP-… reached N%. and the progress never restarted |
btnBell 🔔 n (header) | unread count; clicking it toasts the newest notification |
pnlNotifications / btnMarkRead | the notification records with ● unread markers; Mark all read clears them |
dgvJobs | this tenant's jobs — job number, description, status, progress, rows, who started it, when. The seeded fabrikam import is in the store and never appears here |
prgJob · lblPercent · lblBanner | the progress observer's output; the banner shows a completed-with-errors, cancelled or failed job |
pnlJobDetail (JobDetailPanel) | status history (every transition, with its layer and timestamp) and the rows that failed, by line and ExternalRef |
lblStatus (status bar) | the active job's state in one line: IMP-… running · Processed batch 3 of 10 … |
Where things live
Module 6/
├─ EnterpriseOps.slnx
├─ README.md
└─ EnterpriseOps/
├─ Domain/ WorkOrder.cs (ExternalRef = idempotency key) · ImportRow.cs
├─ Data/ FakeImportFileSource.cs (2 generated files) · FakeWorkOrderRepository.cs (idempotent Upsert)
├─ Services/
│ ├─ ActivityTrace.cs server-side log (System.Diagnostics.Trace)
│ ├─ SessionContext.cs tenant · user · role · correlation ids · CommandResult
│ └─ Jobs/ BackgroundPipelinePatterns · JobModels · JobStatusStore · JobQueue ·
│ NotificationService · RetryPolicy · JobProgressObserver · ImportService · JobInfrastructure
├─ UI/ ImportCenterPage (observer only) · JobDetailPanel (UserControl)
├─ docs/ the five deliverables, the pipeline SVG and the readiness note
├─ Program.cs session entry point: SessionContext in Application.Session
└─ Startup.cs Kestrel host (app.UseWisej())