DEV Community

Cover image for πŸš€ Running Background Jobs in Blazor WASM with WJb (No Backend Required)
Oleksandr Viktor
Oleksandr Viktor

Posted on

πŸš€ Running Background Jobs in Blazor WASM with WJb (No Backend Required)

πŸš€ 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
Enter fullscreen mode Exit fullscreen mode

▢️ Starting a Job

Enqueueing a job is just one line:

private void Start()
{
    Engine.Enqueue<DemoAction, DemoPayload>(
        new DemoPayload
        {
            DelayMs = 5000,
            Text = "Done βœ…"
        });
}
Enter fullscreen mode Exit fullscreen mode

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();
    });
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
})">
Enter fullscreen mode Exit fullscreen mode

And progress is just a Bootstrap bar:

<div class="progress-bar"
     style="width:@t.State.Progress%">
    <small>@t.State.Progress%</small>
</div>
Enter fullscreen mode Exit fullscreen mode

βœ‹ 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);
Enter fullscreen mode Exit fullscreen mode

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>
}
Enter fullscreen mode Exit fullscreen mode

🧩 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:
    • Enqueue
    • Retry
    • Cancel
    • GetAll
  • 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)