π Running Background Jobs in Blazor WASM with WJb (No Backend Required)
Background processing usually implies servers, queues, workers⦠and complexity.
But what if you could run job processing entirely in the browser β with tracking, retries, and cancellation β using a clean API?
Thatβs exactly what WJb enables.
In this article, Iβll show a simple but powerful demo of WJb running inside Blazor WebAssembly, where jobs are:
- β Queued with one click
- β Tracked in real-time
- β Cancelled or retried from the UI
π§ What is WJb?
WJb is a lightweight job engine designed for simplicity:
- Minimal API surface
- Clear job lifecycle (Queued β Processing β Completed/Failed/Cancelled)
- Built-in progress tracking
- Retry & cancellation support
- Works even in WASM (no server required)
π― The Demo
The UI is extremely simple:
- A Run Demo Job button
- A table showing:
- Job ID
- Status
- Progress
- Message
- Attempts
- Actions (Cancel / Retry)
Hereβs the core Razor page:
@page "/"
@using WJb.Abstractions
@using WJb.Core
@using WJb.Demo.Wasm.Actions
@inject IJobEngine Engine
βΆοΈ Starting a Job
Enqueueing a job is just one line:
private void Start()
{
Engine.Enqueue<DemoAction, DemoPayload>(
new DemoPayload
{
DelayMs = 5000,
Text = "Done β
"
});
}
Thatβs it.
No queue setup.
No worker service.
No background host.
Just enqueue and go.
π Real-Time UI Updates
WJb exposes a simple event:
protected override void OnInitialized()
{
Engine.Changed += HandleChanged;
tasks = Engine.GetAll().ToList();
}
private void HandleChanged()
{
InvokeAsync(() =>
{
tasks = Engine.GetAll().ToList();
StateHasChanged();
});
}
Whenever a job updates (progress/status), the UI refreshes automatically.
π Job State Rendering
Each job comes with a state object:
t.State.Status
t.State.Progress
t.State.Message
t.State.Attempts
Rendering status is clean and expressive:
<span class="badge @(t.State.Status switch
{
JobStatus.Processing => "bg-primary",
JobStatus.Completed => "bg-success",
JobStatus.Failed => "bg-danger",
JobStatus.Cancelled => "bg-danger",
_ => "bg-secondary"
})">
And progress is just a Bootstrap bar:
<div class="progress-bar"
style="width:@t.State.Progress%">
<small>@t.State.Progress%</small>
</div>
β Cancel & Retry
WJb supports job control out of the box:
private void Retry(string id) => Engine.Retry(id);
private void Cancel(string id) => Engine.Cancel(id);
UI logic:
@if (t.State.Status is JobStatus.Queued or JobStatus.Processing)
{
<button @onclick="() => Cancel(t.JobId)">β</button>
}
else if (t.State.Status is JobStatus.Failed or JobStatus.Cancelled)
{
<button @onclick="() => Retry(t.JobId)">π</button>
}
π§© The Interesting Part: It Runs in WASM
This is where things get fun.
All of this works:
- β Without ASP.NET backend
- β Without queues like RabbitMQ
- β Without hosted services
The job engine runs inside the browser runtime.
This makes it perfect for:
- Client-side automation
- Long-running UI tasks
- Offline-first applications
- Interactive demos and tooling
π‘ Why This Matters
Most job systems are:
- Heavy
- Infrastructure-dependent
- Hard to integrate into UI
WJb flips that:
| Traditional Jobs | WJb |
|---|---|
| Requires backend | Works in WASM |
| Worker services | In-process engine |
| Complex setup | Simple API |
| Limited UI integration | Built for UI |
π₯ Key Takeaways
- WJb gives you background jobs without infrastructure
- Blazor WASM can handle real-time job processing
- The API is intentionally minimal:
EnqueueRetryCancelGetAll
- UI integration is trivial via
Engine.Changed
π Final Thoughts
This demo is small, but the idea is powerful:
Background processing doesnβt have to mean backend complexity.
With WJb, you can build responsive, controllable job workflows in the browser.
Top comments (0)