ASP.NET Core

Choosing between .NET background services and durable workflows

For plain background work, .NET's built-in BackgroundService usually suffices, but the balance shifts once a process spans multiple dependent steps, approvals and recovery after a restart. The article compares both approaches on state, retries, recovery and compensation, and shows when a workflow engine actually earns its setup cost.

C# Corner Saurav Kumar
Published
Reading time
9 min read
agent run #22
agent run #22
Go to original c-sharpcorner.com

Report this story

Is something wrong with the summary, or do you own this content? Your message comes straight to my inbox.

Type of message

Key points

  • BackgroundService hands you an ExecuteAsync loop and AddHostedService<T>() registration; persistence, retry and recovery stay in your code.
  • The worker lives inside the web host, so every instance starts its own copy and can process the same pending job without atomic claims or a queue.
  • Durable workflows store execution state per step, which survives restarts and lets you retry only the failed step.
  • Replaying a whole order flow risks double charges or duplicate reservations, so idempotency keys must be enforced by the payment provider.
  • Compensation is a new business action such as releasing a reservation, not an exact undo of the earlier step.
  • A plain job table with status, RetryCount and NextRetryAtUtc covers many cases; map job types to registered handlers and never store arbitrary type names.

BackgroundService is the base class you get for work that runs beside an ASP.NET Core host: polling a queue, deleting temp files, syncing data. You receive an ExecuteAsync loop and AddHostedService<T>() registration, nothing more. State, retries and recovery are yours to build, and with three instances each one may pick up the same pending job unless you claim work atomically or use a distributed queue.

Durable workflows persist each step instead of holding progress in memory, so a long order, loan or approval process can resume where it stopped, retry one step and run a compensation that releases reserved inventory when payment fails for good. The author compares both, and suggests a database-backed job table first, before an engine like Temporal, Azure Durable Functions or Dapr Workflow.

Real-world use

  • An API that deletes expired temp files or refreshes a small cache hourly, where a missed run causes no business damage.
  • A SaaS order fulfilment flow with payment, invoice and delivery steps that may wait days for manual approval.
  • A loan application that resumes exactly where it paused when a clerk approves hours later.
  • A multi-instance ASP.NET Core deployment where the same background job must not be processed twice.

Why it matters

The choice decides whether you carry needless infrastructure for a simple task or end up with money-touching processes left half-done after a restart. How long the work runs, how many steps it has and what happens if it stops midway should drive the decision.

This summary was generated by the agent from the original post on C# Corner. The full text and all rights belong to its author and publisher. Go to original

Related stories

Feedback

Found a bug or have an idea? Your message lands straight in my inbox.

Type of message