<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Oleksandr Viktor</title>
    <description>The latest articles on DEV Community by Oleksandr Viktor (@ukrguru).</description>
    <link>https://dev.to/ukrguru</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2645949%2Fc57b0952-c7b2-4419-b654-d898c8c54abf.jpg</url>
      <title>DEV Community: Oleksandr Viktor</title>
      <link>https://dev.to/ukrguru</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ukrguru"/>
    <language>en</language>
    <item>
      <title>Background Jobs Running Directly Inside Blazor WebAssembly? 🤔</title>
      <dc:creator>Oleksandr Viktor</dc:creator>
      <pubDate>Tue, 11 Aug 2026 06:00:13 +0000</pubDate>
      <link>https://dev.to/ukrguru/background-jobs-running-directly-inside-blazor-webassembly-54i0</link>
      <guid>https://dev.to/ukrguru/background-jobs-running-directly-inside-blazor-webassembly-54i0</guid>
      <description>&lt;p&gt;Most job frameworks are built for servers.&lt;/p&gt;

&lt;p&gt;This demo shows WJb running background jobs entirely in the browser, with real-time progress tracking, status updates, chained actions, and a live dashboard.&lt;/p&gt;

&lt;p&gt;✅ Pure Blazor WebAssembly&lt;br&gt;
 ✅ Real-time progress&lt;br&gt;
 ✅ Chained workflows&lt;br&gt;
 ✅ Success / Failure handling&lt;br&gt;
 ✅ Live demo&lt;/p&gt;

&lt;p&gt;🎬 Video:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/shorts/Tu3TD2Rk37E" rel="noopener noreferrer"&gt;https://www.youtube.com/shorts/Tu3TD2Rk37E&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/UkrGuru/WJb.Demo/tree/main/samples/WJb.Demo.Wasm" rel="noopener noreferrer"&gt;https://github.com/UkrGuru/WJb.Demo/tree/main/samples/WJb.Demo.Wasm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would you run job workflows in the browser? What use cases come to mind?&lt;/p&gt;

&lt;h1&gt;
  
  
  dotnet #csharp #blazor #webassembly #workflow #backgroundjobs #opensource
&lt;/h1&gt;

</description>
    </item>
    <item>
      <title>Running Background Jobs in Blazor WebAssembly with WJb</title>
      <dc:creator>Oleksandr Viktor</dc:creator>
      <pubDate>Mon, 10 Aug 2026 17:59:05 +0000</pubDate>
      <link>https://dev.to/ukrguru/running-background-jobs-in-blazor-webassembly-with-wjb-hik</link>
      <guid>https://dev.to/ukrguru/running-background-jobs-in-blazor-webassembly-with-wjb-hik</guid>
      <description>&lt;p&gt;Most background job frameworks are designed for server applications.&lt;/p&gt;

&lt;p&gt;As an experiment, I built a demo showing the WJb background job engine running entirely inside a Blazor WebAssembly app. The demo executes jobs in the browser, tracks progress, updates UI in real time, supports chained actions, and demonstrates success, failure, and cancellation scenarios.&lt;/p&gt;

&lt;p&gt;Key things demonstrated:&lt;/p&gt;

&lt;p&gt;✅ Background job execution in a WASM environment&lt;br&gt;
✅ Real-time progress tracking&lt;br&gt;
✅ Chained actions&lt;br&gt;
✅ Status handling (Completed / Failed)&lt;br&gt;
✅ Live dashboard&lt;br&gt;
✅ Decoupled action architecture&lt;br&gt;
✅ Job cleanup support&lt;/p&gt;

&lt;p&gt;One of my goals with WJb is to keep workflows and jobs as regular C# code instead of introducing DSLs, XML, or designers.&lt;/p&gt;

&lt;p&gt;Source and demo:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/UkrGuru/WJb.Demo/tree/main/samples/WJb.Demo.Wasm" rel="noopener noreferrer"&gt;https://github.com/UkrGuru/WJb.Demo/tree/main/samples/WJb.Demo.Wasm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'd be interested to hear from other .NET developers:&lt;/p&gt;

&lt;p&gt;Would you ever run a job/workflow engine in the browser, and what use cases would justify it?&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>backend</category>
      <category>programming</category>
    </item>
    <item>
      <title>📚 WJb documentation is finally here.</title>
      <dc:creator>Oleksandr Viktor</dc:creator>
      <pubDate>Wed, 05 Aug 2026 19:08:14 +0000</pubDate>
      <link>https://dev.to/ukrguru/wjb-documentation-is-finally-here-8hj</link>
      <guid>https://dev.to/ukrguru/wjb-documentation-is-finally-here-8hj</guid>
      <description>&lt;p&gt;📚 WJb documentation is finally here.&lt;/p&gt;

&lt;p&gt;One of the most common challenges for any open-source project is reducing the entry barrier for new users. Today WJb takes a big step forward with a dedicated documentation guide:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/UkrGuru/WJb.Demo/blob/main/docs/README.md" rel="noopener noreferrer"&gt;https://github.com/UkrGuru/WJb.Demo/blob/main/docs/README.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The guide covers: • Core concepts&lt;br&gt;
 • Workflow structure&lt;br&gt;
 • Configuration examples&lt;br&gt;
 • Getting started steps&lt;br&gt;
 • Practical usage scenarios&lt;/p&gt;

&lt;p&gt;Documentation is never as exciting as implementing new features, but it is often more important for project adoption.&lt;/p&gt;

&lt;p&gt;Feedback is welcome!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Integration Tests for Background Jobs in ASP.NET Core</title>
      <dc:creator>Oleksandr Viktor</dc:creator>
      <pubDate>Tue, 28 Jul 2026 15:21:47 +0000</pubDate>
      <link>https://dev.to/ukrguru/integration-tests-for-background-jobs-in-aspnet-core-1jdn</link>
      <guid>https://dev.to/ukrguru/integration-tests-for-background-jobs-in-aspnet-core-1jdn</guid>
      <description>&lt;p&gt;Integration Tests for Background Jobs in ASP.NET Core&lt;/p&gt;

&lt;p&gt;One thing I always look for in job-processing frameworks is real integration testing, not just unit tests.&lt;/p&gt;

&lt;p&gt;I put together a sample test suite for WJb that shows how to test background jobs end-to-end using ASP.NET Core's test infrastructure:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwnexe4lxn4mw7tztit4q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwnexe4lxn4mw7tztit4q.png" alt=" " width="335" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🔗 &lt;a href="https://github.com/UkrGuru/WJb.Demo/tree/main/test/WJb.IntegrationTests" rel="noopener noreferrer"&gt;https://github.com/UkrGuru/WJb.Demo/tree/main/test/WJb.IntegrationTests&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Highlights:&lt;/p&gt;

&lt;p&gt;✅ Test jobs through a real DI container&lt;br&gt;
✅ Verify execution flow and scheduling behavior&lt;br&gt;
✅ Test worker startup and background processing&lt;br&gt;
✅ Keep tests deterministic and easy to understand&lt;br&gt;
✅ No mocking of the framework internals&lt;/p&gt;

&lt;p&gt;If you're building background processing solutions in .NET, integration tests like these can catch issues that unit tests often miss.&lt;/p&gt;

&lt;h1&gt;
  
  
  dotnet #aspnetcore #testing #integrationtesting #backgroundjobs #opensource #csharp #wjb
&lt;/h1&gt;

</description>
      <category>dotnet</category>
      <category>aspnetcore</category>
      <category>csharp</category>
    </item>
    <item>
      <title>WJb vs Hangfire vs Quartz: Same Benchmarks, Same Machine</title>
      <dc:creator>Oleksandr Viktor</dc:creator>
      <pubDate>Mon, 27 Jul 2026 08:36:07 +0000</pubDate>
      <link>https://dev.to/ukrguru/-wjb-vs-hangfire-vs-quartz-same-benchmarks-same-machine-141d</link>
      <guid>https://dev.to/ukrguru/-wjb-vs-hangfire-vs-quartz-same-benchmarks-same-machine-141d</guid>
      <description>&lt;h1&gt;
  
  
  WJb vs Hangfire vs Quartz: Same Benchmarks, Same Machine
&lt;/h1&gt;

&lt;p&gt;Background job libraries are usually compared by features.&lt;/p&gt;

&lt;p&gt;This benchmark compares something simpler:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How fast can they enqueue work?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/UkrGuru/WJb.Demo/tree/main/benchmark" rel="noopener noreferrer"&gt;https://github.com/UkrGuru/WJb.Demo/tree/main/benchmark&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1oghsp7dv8ps8syms8di.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1oghsp7dv8ps8syms8di.gif" alt="WJb Benchmarks" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Benchmarks were implemented separately for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WJb&lt;/li&gt;
&lt;li&gt;Hangfire&lt;/li&gt;
&lt;li&gt;Quartz&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BenchmarkDotNet&lt;/li&gt;
&lt;li&gt;In-memory storage&lt;/li&gt;
&lt;li&gt;No-op jobs/actions&lt;/li&gt;
&lt;li&gt;Equivalent benchmark scenarios&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Single Enqueue
&lt;/h2&gt;

&lt;p&gt;Enqueue one job.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Memory&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;WJb&lt;/td&gt;
&lt;td&gt;349 ns&lt;/td&gt;
&lt;td&gt;328 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quartz&lt;/td&gt;
&lt;td&gt;3.848 μs&lt;/td&gt;
&lt;td&gt;3.08 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hangfire&lt;/td&gt;
&lt;td&gt;6.212 μs&lt;/td&gt;
&lt;td&gt;11.46 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Result
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;WJb ≈ 11× faster than Quartz&lt;/li&gt;
&lt;li&gt;WJb ≈ 18× faster than Hangfire&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  EnqueueMany (100,000 Jobs)
&lt;/h2&gt;

&lt;p&gt;Bulk enqueue benchmark.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Memory&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;WJb&lt;/td&gt;
&lt;td&gt;32 ms&lt;/td&gt;
&lt;td&gt;31 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hangfire&lt;/td&gt;
&lt;td&gt;743 ms&lt;/td&gt;
&lt;td&gt;1063 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quartz&lt;/td&gt;
&lt;td&gt;902 ms&lt;/td&gt;
&lt;td&gt;539 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Result
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;WJb ≈ 23× faster than Hangfire&lt;/li&gt;
&lt;li&gt;WJb ≈ 28× faster than Quartz&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Parallel Enqueue (100,000 Jobs)
&lt;/h2&gt;

&lt;p&gt;Multiple concurrent producers.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;Best Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;WJb&lt;/td&gt;
&lt;td&gt;52 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hangfire&lt;/td&gt;
&lt;td&gt;540 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quartz&lt;/td&gt;
&lt;td&gt;600 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Memory Usage
&lt;/h2&gt;

&lt;p&gt;100,000 jobs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;Memory&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;WJb&lt;/td&gt;
&lt;td&gt;31 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quartz&lt;/td&gt;
&lt;td&gt;539 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hangfire&lt;/td&gt;
&lt;td&gt;1063 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Result
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;WJb uses ~17× less memory than Quartz&lt;/li&gt;
&lt;li&gt;WJb uses ~34× less memory than Hangfire&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why WJb?
&lt;/h2&gt;

&lt;p&gt;WJb was designed around a very small execution model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enqueue
  ↓
job
  ↓
action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No dashboard.&lt;/p&gt;

&lt;p&gt;No workflow engine.&lt;/p&gt;

&lt;p&gt;No implicit pipeline.&lt;/p&gt;

&lt;p&gt;Just explicit background jobs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Reproduce
&lt;/h2&gt;

&lt;p&gt;Source code is included:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WJb.Benchmarks
WJb.Benchmarks.Hangfire
WJb.Benchmarks.Quartz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet run &lt;span class="nt"&gt;-c&lt;/span&gt; Release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Final Numbers
&lt;/h2&gt;

&lt;p&gt;For these benchmark scenarios:&lt;/p&gt;

&lt;p&gt;✅ Fastest enqueue: &lt;strong&gt;WJb&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✅ Fastest bulk enqueue: &lt;strong&gt;WJb&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✅ Fastest parallel enqueue: &lt;strong&gt;WJb&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✅ Lowest memory usage: &lt;strong&gt;WJb&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Benchmark scenarios are intentionally small, reproducible, and focused on enqueue performance.&lt;br&gt;
Additional scenarios will be added only when equivalent implementations exist for all compared libraries.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>ai</category>
      <category>dotnet</category>
      <category>programming</category>
    </item>
    <item>
      <title>Why WJb?</title>
      <dc:creator>Oleksandr Viktor</dc:creator>
      <pubDate>Thu, 23 Jul 2026 10:13:05 +0000</pubDate>
      <link>https://dev.to/ukrguru/why-wjb-30c1</link>
      <guid>https://dev.to/ukrguru/why-wjb-30c1</guid>
      <description>&lt;h1&gt;
  
  
  Why WJb?
&lt;/h1&gt;

&lt;p&gt;WJb is a lightweight workflow engine for .NET that lets you orchestrate business processes using plain C# code.&lt;/p&gt;

&lt;p&gt;No DSLs. No XML. No visual designers. No mandatory infrastructure.&lt;/p&gt;

&lt;p&gt;Build workflows the same way you build the rest of your application.&lt;/p&gt;




&lt;h1&gt;
  
  
  Key Advantages
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Zero Required Dependencies
&lt;/h2&gt;

&lt;p&gt;WJb can be added to almost any .NET application without introducing infrastructure requirements.&lt;/p&gt;

&lt;p&gt;You do &lt;strong&gt;not&lt;/strong&gt; need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQL Server&lt;/li&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt;RabbitMQ&lt;/li&gt;
&lt;li&gt;Kafka&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Kubernetes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Install the package and start building workflows immediately.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Works Anywhere .NET Runs
&lt;/h2&gt;

&lt;p&gt;WJb is not tied to a specific hosting model.&lt;/p&gt;

&lt;p&gt;Use it in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ASP.NET Core applications&lt;/li&gt;
&lt;li&gt;Console applications&lt;/li&gt;
&lt;li&gt;Worker Services&lt;/li&gt;
&lt;li&gt;Windows Services&lt;/li&gt;
&lt;li&gt;Linux services&lt;/li&gt;
&lt;li&gt;Docker containers&lt;/li&gt;
&lt;li&gt;Azure-hosted applications&lt;/li&gt;
&lt;li&gt;IIS-hosted applications&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Fast and Simple to Start
&lt;/h2&gt;

&lt;p&gt;Your first workflow can be running within minutes.&lt;/p&gt;

&lt;p&gt;There is no need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploy additional services&lt;/li&gt;
&lt;li&gt;Configure message brokers&lt;/li&gt;
&lt;li&gt;Learn a workflow-specific language&lt;/li&gt;
&lt;li&gt;Set up distributed infrastructure&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Workflows Are Just C
&lt;/h2&gt;

&lt;p&gt;WJb embraces the language you already use every day.&lt;/p&gt;

&lt;p&gt;No:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DSL&lt;/li&gt;
&lt;li&gt;XML&lt;/li&gt;
&lt;li&gt;YAML&lt;/li&gt;
&lt;li&gt;JSON workflow definitions&lt;/li&gt;
&lt;li&gt;Visual process designers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use familiar .NET concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Classes&lt;/li&gt;
&lt;li&gt;Interfaces&lt;/li&gt;
&lt;li&gt;Dependency Injection&lt;/li&gt;
&lt;li&gt;Generics&lt;/li&gt;
&lt;li&gt;Async/await&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. Full IDE Support
&lt;/h2&gt;

&lt;p&gt;Because workflows are regular C# code, your IDE understands them completely.&lt;/p&gt;

&lt;p&gt;You get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go To Definition&lt;/li&gt;
&lt;li&gt;Find Usages&lt;/li&gt;
&lt;li&gt;Rename Refactoring&lt;/li&gt;
&lt;li&gt;Code Navigation&lt;/li&gt;
&lt;li&gt;IntelliSense&lt;/li&gt;
&lt;li&gt;Debugging&lt;/li&gt;
&lt;li&gt;Breakpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No special tooling required.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Minimal Learning Curve
&lt;/h2&gt;

&lt;p&gt;If you already know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;C#&lt;/li&gt;
&lt;li&gt;Dependency Injection&lt;/li&gt;
&lt;li&gt;Async programming&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;you already know most of what is needed to be productive with WJb.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Actions Are Simple Classes
&lt;/h2&gt;

&lt;p&gt;Each workflow step is an individual Action.&lt;/p&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clear responsibility&lt;/li&gt;
&lt;li&gt;Easy maintenance&lt;/li&gt;
&lt;li&gt;Reusability&lt;/li&gt;
&lt;li&gt;Better testability&lt;/li&gt;
&lt;li&gt;Better readability&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  8. Readable Business Processes
&lt;/h2&gt;

&lt;p&gt;Large business processes often become scattered across services, controllers, event handlers, and background tasks.&lt;/p&gt;

&lt;p&gt;WJb keeps workflow logic organized and visible.&lt;/p&gt;

&lt;p&gt;A developer can quickly understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where execution starts&lt;/li&gt;
&lt;li&gt;Which steps run&lt;/li&gt;
&lt;li&gt;Where decisions are made&lt;/li&gt;
&lt;li&gt;How the process ends&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  9. Reusable Building Blocks
&lt;/h2&gt;

&lt;p&gt;Actions can be reused across multiple workflows.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validation actions&lt;/li&gt;
&lt;li&gt;API integration actions&lt;/li&gt;
&lt;li&gt;Email actions&lt;/li&gt;
&lt;li&gt;Database actions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Build once and use everywhere.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Easy Unit Testing
&lt;/h2&gt;

&lt;p&gt;Workflows and Actions can be tested independently.&lt;/p&gt;

&lt;p&gt;You can test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single actions&lt;/li&gt;
&lt;li&gt;Action chains&lt;/li&gt;
&lt;li&gt;Complete workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without running external infrastructure.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. Architecture-Friendly
&lt;/h2&gt;

&lt;p&gt;WJb does not force a specific architectural style.&lt;/p&gt;

&lt;p&gt;It works well with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clean Architecture&lt;/li&gt;
&lt;li&gt;Modular Monolith&lt;/li&gt;
&lt;li&gt;Vertical Slice Architecture&lt;/li&gt;
&lt;li&gt;Layered Architecture&lt;/li&gt;
&lt;li&gt;CQRS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;WJb complements your architecture instead of replacing it.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. No Mandatory Message Queues
&lt;/h2&gt;

&lt;p&gt;Many workflow systems assume queues are always required.&lt;/p&gt;

&lt;p&gt;WJb does not.&lt;/p&gt;

&lt;p&gt;If your solution needs a queue, use one.&lt;/p&gt;

&lt;p&gt;If it does not, you can keep your system simple.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. No Mandatory Database
&lt;/h2&gt;

&lt;p&gt;For simple scenarios, workflows can run entirely in memory.&lt;/p&gt;

&lt;p&gt;When persistent state becomes necessary, you can add &lt;strong&gt;WJb.Sql&lt;/strong&gt; without changing your workflow design.&lt;/p&gt;




&lt;h2&gt;
  
  
  14. Grow at Your Own Pace
&lt;/h2&gt;

&lt;p&gt;A typical adoption path looks like this:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1
&lt;/h3&gt;

&lt;p&gt;Use WJb for workflow orchestration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2
&lt;/h3&gt;

&lt;p&gt;Add WJb.Sql for persistence and durability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3
&lt;/h3&gt;

&lt;p&gt;Add WJb.Pro for monitoring and management capabilities.&lt;/p&gt;

&lt;p&gt;Start small and expand only when needed.&lt;/p&gt;




&lt;h2&gt;
  
  
  15. Complete Workflow Visibility
&lt;/h2&gt;

&lt;p&gt;A workflow is defined in one place.&lt;/p&gt;

&lt;p&gt;Developers can easily see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entry points&lt;/li&gt;
&lt;li&gt;Workflow steps&lt;/li&gt;
&lt;li&gt;Branches&lt;/li&gt;
&lt;li&gt;Error paths&lt;/li&gt;
&lt;li&gt;Completion paths&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This significantly improves maintainability.&lt;/p&gt;




&lt;h2&gt;
  
  
  16. Ideal for Long-Running Processes
&lt;/h2&gt;

&lt;p&gt;WJb is a natural fit for workflows such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User onboarding&lt;/li&gt;
&lt;li&gt;Order processing&lt;/li&gt;
&lt;li&gt;Approval flows&lt;/li&gt;
&lt;li&gt;Document processing&lt;/li&gt;
&lt;li&gt;Data imports&lt;/li&gt;
&lt;li&gt;System integrations&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  17. Small Core, Few Concepts
&lt;/h2&gt;

&lt;p&gt;You do not need to learn an entirely new platform.&lt;/p&gt;

&lt;p&gt;The core concepts are intentionally small and focused.&lt;/p&gt;

&lt;p&gt;This helps teams become productive quickly.&lt;/p&gt;




&lt;h2&gt;
  
  
  18. Perfect for Small Teams
&lt;/h2&gt;

&lt;p&gt;Many workflow platforms assume large teams and dedicated infrastructure engineers.&lt;/p&gt;

&lt;p&gt;WJb works especially well for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Solo developers&lt;/li&gt;
&lt;li&gt;Small development teams&lt;/li&gt;
&lt;li&gt;Startups&lt;/li&gt;
&lt;li&gt;Internal business applications&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  19. Ready for Enterprise Systems
&lt;/h2&gt;

&lt;p&gt;WJb can support workflows behind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CRM systems&lt;/li&gt;
&lt;li&gt;ERP systems&lt;/li&gt;
&lt;li&gt;Financial platforms&lt;/li&gt;
&lt;li&gt;Document management systems&lt;/li&gt;
&lt;li&gt;Integration solutions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simple enough to start, powerful enough to scale.&lt;/p&gt;




&lt;h2&gt;
  
  
  20. Stays Inside Your Application
&lt;/h2&gt;

&lt;p&gt;Your workflow engine remains part of your application rather than becoming a separate platform.&lt;/p&gt;

&lt;p&gt;Benefits include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One repository&lt;/li&gt;
&lt;li&gt;One deployment pipeline&lt;/li&gt;
&lt;li&gt;One testing strategy&lt;/li&gt;
&lt;li&gt;One development experience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything remains in familiar .NET code.&lt;/p&gt;




&lt;h1&gt;
  
  
  In One Sentence
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;WJb lets you build workflows using plain C#, with zero required infrastructure, full IDE support, excellent testability, and a clear upgrade path from simple in-memory workflows to production-grade persistent workflow orchestration.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NuGet Packages:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.nuget.org/packages?q=wjb" rel="noopener noreferrer"&gt;https://www.nuget.org/packages?q=wjb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo Repository:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/UkrGuru/WJb.Demo" rel="noopener noreferrer"&gt;https://github.com/UkrGuru/WJb.Demo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>If You Can't Explain Why a Background Job Runs, You Don't Control Your System</title>
      <dc:creator>Oleksandr Viktor</dc:creator>
      <pubDate>Wed, 22 Jul 2026 13:15:50 +0000</pubDate>
      <link>https://dev.to/ukrguru/if-you-cant-explain-why-a-background-job-runs-you-dont-control-your-system-2i3e</link>
      <guid>https://dev.to/ukrguru/if-you-cant-explain-why-a-background-job-runs-you-dont-control-your-system-2i3e</guid>
      <description>&lt;p&gt;Background job systems are everywhere.&lt;/p&gt;

&lt;p&gt;Send an email.&lt;br&gt;&lt;br&gt;
Generate a report.&lt;br&gt;&lt;br&gt;
Process a payment.&lt;br&gt;&lt;br&gt;
Synchronize data.&lt;/p&gt;

&lt;p&gt;Most applications start simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Job
 ↓
Execute
 ↓
Done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then a few months later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Job
 ↓
Retry
 ↓
Pipeline
 ↓
Middleware
 ↓
Filters
 ↓
Background magic
 ↓
???
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And eventually someone asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why did this job run?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nobody is quite sure.&lt;/p&gt;

&lt;p&gt;Imagine a production incident.&lt;/p&gt;

&lt;p&gt;A background job sent thousands of emails.&lt;/p&gt;

&lt;p&gt;The logs show success.&lt;/p&gt;

&lt;p&gt;The dashboard shows success.&lt;/p&gt;

&lt;p&gt;The scheduler shows success.&lt;/p&gt;

&lt;p&gt;Yet nobody can answer a simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why did this job run?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question became the starting point for my design decisions.&lt;/p&gt;




&lt;h2&gt;
  
  
  When Execution Becomes Hard to Follow
&lt;/h2&gt;

&lt;p&gt;Modern background processing systems provide powerful abstractions.&lt;/p&gt;

&lt;p&gt;The problem is that every abstraction introduces another place where execution flow can hide.&lt;/p&gt;

&lt;p&gt;Questions become surprisingly difficult:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why was this job retried?&lt;/li&gt;
&lt;li&gt;What scheduled the next step?&lt;/li&gt;
&lt;li&gt;Which component modified execution?&lt;/li&gt;
&lt;li&gt;Why did this workflow reach its current state?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The system works.&lt;/p&gt;

&lt;p&gt;But understanding the system becomes harder over time.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Different Approach
&lt;/h2&gt;

&lt;p&gt;While working on workflow and job execution systems, I kept coming back to a simple idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Every execution step should be explicit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of hidden orchestration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Job
 ↓
Framework
 ↓
Magic
 ↓
Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I prefer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Job
 ↓
Executor
 ↓
Action
 ↓
ActionResult
 ↓
JobCommand
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every step is visible.&lt;/p&gt;

&lt;p&gt;Every transition is intentional.&lt;/p&gt;

&lt;p&gt;Every workflow can be traced by reading code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Workflows Should Be Code
&lt;/h2&gt;

&lt;p&gt;Consider a simple process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Send Email
 ↓
Write Log
 ↓
Done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In WJb, an action explicitly decides what happens next.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ActionResults&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;JobCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;Actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;LogInput&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$"Email sent to &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;To&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The workflow is not hidden in configuration.&lt;/p&gt;

&lt;p&gt;The workflow is not hidden in a dashboard.&lt;/p&gt;

&lt;p&gt;The workflow is not hidden inside middleware.&lt;/p&gt;

&lt;p&gt;It is right there in the action.&lt;/p&gt;




&lt;h2&gt;
  
  
  Traditional Thinking vs Explicit Execution
&lt;/h2&gt;

&lt;p&gt;Traditional approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Job
 ↓
Scheduler
 ↓
Retry Logic
 ↓
Filters
 ↓
Pipeline
 ↓
Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explicit execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Job
 ↓
Action
 ↓
ActionResult
 ↓
JobCommand
 ↓
Next Action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference is not performance.&lt;/p&gt;

&lt;p&gt;The difference is understanding what happens when something goes wrong.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Does a Minimal Workflow Look Like?
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;send-email → log → done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;wjb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EnqueueAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SendEmail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;EmailInput&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;To&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"user@test.com"&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;wjb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExecuteLoopAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The complete example is small enough to understand in a few minutes.&lt;/p&gt;

&lt;p&gt;No special DSL.&lt;/p&gt;

&lt;p&gt;No separate workflow engine.&lt;/p&gt;

&lt;p&gt;No conventions that require documentation to discover.&lt;/p&gt;




&lt;h2&gt;
  
  
  Explicit Retries
&lt;/h2&gt;

&lt;p&gt;Retries are part of the job configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;wjb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EnqueueAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;RetryAction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;EmptyInput&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;JobOptions&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;MaxRetries&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;RetryDelay&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execution flow remains predictable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Attempt 1
 ↓
Failed
 ↓
Retry Job Created
 ↓
Attempt 2
 ↓
Completed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing mysterious happens behind the scenes.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Question I Use During Reviews
&lt;/h2&gt;

&lt;p&gt;When reviewing a background processing system, I ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why did this job run?&lt;/li&gt;
&lt;li&gt;Who scheduled it?&lt;/li&gt;
&lt;li&gt;Why was it retried?&lt;/li&gt;
&lt;li&gt;What happens next?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If answering those questions requires opening dashboards, configuration files, middleware registrations and framework internals, the execution model may be more complicated than necessary.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Built WJb
&lt;/h2&gt;

&lt;p&gt;The goal was never to create another scheduler.&lt;/p&gt;

&lt;p&gt;The goal was to build a system where you can answer four simple questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why did a job start?&lt;/li&gt;
&lt;li&gt;What did it do?&lt;/li&gt;
&lt;li&gt;What did it schedule next?&lt;/li&gt;
&lt;li&gt;Why was it retried?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If those questions are difficult to answer, debugging production systems becomes harder than it should be.&lt;/p&gt;




&lt;h2&gt;
  
  
  Predictability First, Performance Second
&lt;/h2&gt;

&lt;p&gt;Predictability was the primary goal.&lt;/p&gt;

&lt;p&gt;Performance turned out to be a nice side effect.&lt;/p&gt;

&lt;p&gt;Recent BenchmarkDotNet measurements on .NET 10 produced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CreateOnly       64.9 ns
ExecuteOnly       8.9 ns
CreateAndExecute 75.1 ns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not bad for a lightweight open source project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Explore the demo project and examples:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/UkrGuru/WJb.Demo" rel="noopener noreferrer"&gt;https://github.com/UkrGuru/WJb.Demo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Browse all WJb packages:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.nuget.org/packages?q=wjb" rel="noopener noreferrer"&gt;https://www.nuget.org/packages?q=wjb&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Is WJb Right for You?
&lt;/h2&gt;

&lt;p&gt;WJb may be interesting if you want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;explicit workflows&lt;/li&gt;
&lt;li&gt;strongly typed actions&lt;/li&gt;
&lt;li&gt;predictable execution&lt;/li&gt;
&lt;li&gt;constructor injection&lt;/li&gt;
&lt;li&gt;simple orchestration&lt;/li&gt;
&lt;li&gt;testable business logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It may not be the right tool if you prefer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;convention-driven behavior&lt;/li&gt;
&lt;li&gt;hidden orchestration&lt;/li&gt;
&lt;li&gt;execution pipelines that aren't visible in code&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;Background jobs should not feel mysterious.&lt;/p&gt;

&lt;p&gt;A workflow should be understandable by reading the code that defines it.&lt;/p&gt;

&lt;p&gt;That's the principle behind WJb:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Action       = Business Logic
ActionResult = Outcome
JobCommand   = Next Step
Executor     = Runner
Store        = Persistence
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should always know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;why a job started&lt;/li&gt;
&lt;li&gt;what it did&lt;/li&gt;
&lt;li&gt;what it scheduled next&lt;/li&gt;
&lt;li&gt;why it was retried&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No magic.&lt;/p&gt;

&lt;p&gt;Just explicit execution.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;NuGet Packages:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.nuget.org/packages?q=wjb" rel="noopener noreferrer"&gt;https://www.nuget.org/packages?q=wjb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo Repository:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/UkrGuru/WJb.Demo" rel="noopener noreferrer"&gt;https://github.com/UkrGuru/WJb.Demo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>backend</category>
      <category>workflow</category>
      <category>aspnetcore</category>
    </item>
    <item>
      <title>Fresh BenchmarkDotNet numbers for WJb on .NET 10:</title>
      <dc:creator>Oleksandr Viktor</dc:creator>
      <pubDate>Sun, 19 Jul 2026 08:30:10 +0000</pubDate>
      <link>https://dev.to/ukrguru/fresh-benchmarkdotnet-numbers-for-wjb-on-net-10-5gl3</link>
      <guid>https://dev.to/ukrguru/fresh-benchmarkdotnet-numbers-for-wjb-on-net-10-5gl3</guid>
      <description>&lt;p&gt;WJb Core benchmark results:&lt;/p&gt;

&lt;p&gt;CreateOnly: 64.9 ns&lt;br&gt;
ExecuteOnly: 8.9 ns&lt;br&gt;
CreateAndExecute: 75.1 ns&lt;/p&gt;

&lt;p&gt;At this point, the profiler spends more time blinking than WJb spends executing.&lt;/p&gt;

&lt;p&gt;Good luck catching up. 🚀&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjkxewkcrxkaccqzigxy6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjkxewkcrxkaccqzigxy6.png" alt=" " width="800" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.nuget.org/packages?q=WJb" rel="noopener noreferrer"&gt;https://www.nuget.org/packages?q=WJb&lt;/a&gt;&lt;/p&gt;

</description>
      <category>hangfire</category>
      <category>quartz</category>
      <category>ai</category>
      <category>dotnetcore</category>
    </item>
    <item>
      <title>WJb Ecosystem vs Hangfire vs Quartz.NET</title>
      <dc:creator>Oleksandr Viktor</dc:creator>
      <pubDate>Sun, 19 Jul 2026 06:30:24 +0000</pubDate>
      <link>https://dev.to/ukrguru/-wjb-ecosystem-vs-hangfire-vs-quartznet-535i</link>
      <guid>https://dev.to/ukrguru/-wjb-ecosystem-vs-hangfire-vs-quartznet-535i</guid>
      <description>&lt;h2&gt;
  
  
  Why I Would Choose WJb
&lt;/h2&gt;

&lt;p&gt;The .NET ecosystem already has two well-known background processing solutions: &lt;strong&gt;Hangfire&lt;/strong&gt; and &lt;strong&gt;Quartz.NET&lt;/strong&gt;. Both are mature, battle-tested, and widely adopted.&lt;/p&gt;

&lt;p&gt;However, the &lt;strong&gt;WJb Ecosystem&lt;/strong&gt; takes a fundamentally different approach.&lt;/p&gt;

&lt;p&gt;Instead of focusing solely on scheduling jobs, WJb focuses on building a lightweight, high-performance, and extensible execution platform with a clean separation between execution, storage, hosting, and monitoring.&lt;/p&gt;

&lt;p&gt;For many modern .NET applications, this architectural approach can be more valuable than simply having another scheduler.&lt;/p&gt;




&lt;h1&gt;
  
  
  Quick Summary
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Recommended Choice&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Need a proven solution with a huge ecosystem&lt;/td&gt;
&lt;td&gt;Hangfire&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Need advanced scheduling and complex cron support&lt;/td&gt;
&lt;td&gt;Quartz.NET&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Need a lightweight, modern, extensible execution engine&lt;/td&gt;
&lt;td&gt;WJb&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;My personal choice for most new .NET projects would be &lt;strong&gt;WJb&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Feature Comparison
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;WJb Ecosystem&lt;/th&gt;
&lt;th&gt;Hangfire&lt;/th&gt;
&lt;th&gt;Quartz.NET&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Background Jobs&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delayed Jobs&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recurring Jobs&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SQL Storage&lt;/td&gt;
&lt;td&gt;✅ WJb.Sql&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitoring UI&lt;/td&gt;
&lt;td&gt;✅ WJb.UI.Blazor&lt;/td&gt;
&lt;td&gt;✅ Dashboard&lt;/td&gt;
&lt;td&gt;❌ Built separately&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dependency Injection&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extensibility&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lightweight Design&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modern .NET Focus&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Learning Curve&lt;/td&gt;
&lt;td&gt;✅ Low&lt;/td&gt;
&lt;td&gt;✅ Medium&lt;/td&gt;
&lt;td&gt;❌ High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure Overhead&lt;/td&gt;
&lt;td&gt;✅ Low&lt;/td&gt;
&lt;td&gt;⚠️ Medium&lt;/td&gt;
&lt;td&gt;❌ High&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  Architectural Comparison
&lt;/h1&gt;

&lt;h2&gt;
  
  
  WJb
&lt;/h2&gt;

&lt;p&gt;The WJb ecosystem is built around clear separation of concerns.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WJb
├── Execution
├── Storage
├── Hosting
├── Monitoring UI
└── Extensions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every layer can evolve independently.&lt;/p&gt;

&lt;p&gt;The core engine remains small, understandable, and easy to debug.&lt;/p&gt;




&lt;h2&gt;
  
  
  Hangfire
&lt;/h2&gt;

&lt;p&gt;Hangfire is built around serialized method execution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Method Call
    ↓
Serialization
    ↓
Storage
    ↓
State Machine
    ↓
Execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This model provides excellent convenience but introduces additional infrastructure and internal complexity.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quartz.NET
&lt;/h2&gt;

&lt;p&gt;Quartz is primarily an enterprise scheduling platform.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scheduler
    ↓
Trigger
    ↓
Calendar
    ↓
Job Store
    ↓
Job Execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is extremely powerful for scheduling scenarios but can feel heavy for many business applications.&lt;/p&gt;




&lt;h1&gt;
  
  
  What Makes WJb Different
&lt;/h1&gt;

&lt;p&gt;The biggest difference is philosophy.&lt;/p&gt;

&lt;p&gt;Hangfire and Quartz were originally designed to answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When should work execute?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;WJb focuses on:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How should work be executed?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This leads to a cleaner and more flexible architecture.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why I Prefer WJb Over Hangfire
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Cleaner Architecture
&lt;/h2&gt;

&lt;p&gt;Hangfire revolves around storing and replaying method invocations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;BackgroundJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Enqueue&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;SendEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is convenient but tightly couples execution to method serialization.&lt;/p&gt;

&lt;p&gt;WJb uses a more explicit execution model.&lt;/p&gt;

&lt;p&gt;The result is greater transparency and easier customization.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Less Framework Magic
&lt;/h2&gt;

&lt;p&gt;Hangfire contains many internal concepts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Jobs
Queues
States
Retries
Commands
Continuations
State Machines
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While powerful, they require developers to understand Hangfire internals.&lt;/p&gt;

&lt;p&gt;WJb exposes a much simpler mental model.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Better Separation of Concerns
&lt;/h2&gt;

&lt;p&gt;One of WJb's strongest design decisions is explicit separation between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Execution
Storage
Hosting
Monitoring
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Benefits include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easier testing&lt;/li&gt;
&lt;li&gt;Easier maintenance&lt;/li&gt;
&lt;li&gt;Better extensibility&lt;/li&gt;
&lt;li&gt;Lower coupling&lt;/li&gt;
&lt;li&gt;Cleaner abstractions&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Modern Blazor-Based UI
&lt;/h2&gt;

&lt;p&gt;WJb.UI.Blazor provides a modern approach to monitoring and administration.&lt;/p&gt;

&lt;p&gt;Advantages include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Component-based architecture&lt;/li&gt;
&lt;li&gt;Easy customization&lt;/li&gt;
&lt;li&gt;Native Blazor integration&lt;/li&gt;
&lt;li&gt;Rich administration experiences&lt;/li&gt;
&lt;li&gt;Consistent .NET development stack&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compared to traditional dashboards, this approach feels more future-oriented.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Complete Control
&lt;/h2&gt;

&lt;p&gt;One of the biggest advantages of WJb is visibility.&lt;/p&gt;

&lt;p&gt;The framework does not try to hide execution details behind multiple abstraction layers.&lt;/p&gt;

&lt;p&gt;Developers maintain control over how jobs are executed, stored, monitored, and extended.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why I Prefer WJb Over Quartz.NET
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Lower Complexity
&lt;/h2&gt;

&lt;p&gt;Quartz introduces many concepts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IScheduler
IJob
ITrigger
Calendar
Listener
JobStore
Misfire Policies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These features are useful but increase complexity significantly.&lt;/p&gt;

&lt;p&gt;Most applications never utilize the full capabilities of Quartz.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Faster Onboarding
&lt;/h2&gt;

&lt;p&gt;Typical onboarding experience:&lt;/p&gt;

&lt;h3&gt;
  
  
  Quartz.NET
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1-3 days
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  WJb
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1-2 hours
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A simpler architecture allows new developers to become productive much faster.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Focus on Business Execution
&lt;/h2&gt;

&lt;p&gt;Quartz focuses on scheduling.&lt;/p&gt;

&lt;p&gt;WJb focuses on execution.&lt;/p&gt;

&lt;p&gt;In many business systems, execution pipelines are more important than complex scheduling rules.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Ecosystem Advantage
&lt;/h1&gt;

&lt;p&gt;The most interesting aspect is not the core package alone.&lt;/p&gt;

&lt;p&gt;It is the ecosystem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WJb
├── WJb.Sql
├── WJb.UI.Blazor
└── WJb.Pro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This modular structure resembles successful .NET ecosystems such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Serilog
MassTransit
Entity Framework
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A lightweight core combined with optional modules typically scales much better than a monolithic framework.&lt;/p&gt;




&lt;h1&gt;
  
  
  Areas Where Hangfire Still Wins
&lt;/h1&gt;

&lt;p&gt;To be fair, Hangfire remains stronger in several areas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maturity
&lt;/h2&gt;

&lt;p&gt;Hangfire has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Many years of production usage&lt;/li&gt;
&lt;li&gt;Large community adoption&lt;/li&gt;
&lt;li&gt;Extensive documentation&lt;/li&gt;
&lt;li&gt;Numerous tutorials&lt;/li&gt;
&lt;li&gt;Large ecosystem support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This significantly reduces adoption risk.&lt;/p&gt;




&lt;h2&gt;
  
  
  Third-Party Integrations
&lt;/h2&gt;

&lt;p&gt;Hangfire offers a very large collection of storage providers and integrations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQL Server&lt;/li&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt;MongoDB&lt;/li&gt;
&lt;li&gt;Azure Services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Its ecosystem is currently much larger.&lt;/p&gt;




&lt;h2&gt;
  
  
  Industry Recognition
&lt;/h2&gt;

&lt;p&gt;Most architects and developers immediately recognize:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hangfire
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WJb is still building that brand recognition.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why I Would Personally Choose WJb Today
&lt;/h1&gt;

&lt;p&gt;Ignoring popularity and focusing purely on architecture, I would choose WJb because of:&lt;/p&gt;

&lt;h2&gt;
  
  
  Simplicity
&lt;/h2&gt;

&lt;p&gt;Less infrastructure.&lt;/p&gt;

&lt;p&gt;Less complexity.&lt;/p&gt;

&lt;p&gt;Less maintenance.&lt;/p&gt;




&lt;h2&gt;
  
  
  Modern Design
&lt;/h2&gt;

&lt;p&gt;WJb feels designed specifically for modern .NET.&lt;/p&gt;

&lt;p&gt;Not adapted to it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architectural Clarity
&lt;/h2&gt;

&lt;p&gt;The framework makes execution behavior visible and understandable.&lt;/p&gt;

&lt;p&gt;Debugging and troubleshooting become significantly easier.&lt;/p&gt;




&lt;h2&gt;
  
  
  Blazor Administration
&lt;/h2&gt;

&lt;p&gt;WJb.UI.Blazor provides an administration experience that aligns naturally with modern .NET applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  Growth Potential
&lt;/h2&gt;

&lt;p&gt;WJb currently has many characteristics historically shared by successful infrastructure projects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Focused
Lightweight
Modern
Fast
Extensible
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These qualities often matter more in the long run than initial popularity.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Verdict
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Hangfire&lt;/strong&gt; is an excellent background job processor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quartz.NET&lt;/strong&gt; is an excellent scheduler.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WJb Ecosystem&lt;/strong&gt; is a modern execution platform designed around simplicity, extensibility, and architectural clarity.&lt;/p&gt;

&lt;p&gt;If I were starting a new .NET project today and evaluating technology primarily from an engineering perspective, I would most likely choose &lt;strong&gt;WJb&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Because in many modern systems:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Simplicity beats complexity.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And WJb achieves that simplicity without sacrificing extensibility.&lt;/p&gt;

</description>
      <category>hangfire</category>
      <category>quartz</category>
      <category>dotnet</category>
      <category>sql</category>
    </item>
    <item>
      <title>🚀 New WJb Demo: Workflow Monitoring in Action</title>
      <dc:creator>Oleksandr Viktor</dc:creator>
      <pubDate>Sat, 18 Jul 2026 18:09:39 +0000</pubDate>
      <link>https://dev.to/ukrguru/-new-wjb-demo-workflow-monitoring-in-action-4cld</link>
      <guid>https://dev.to/ukrguru/-new-wjb-demo-workflow-monitoring-in-action-4cld</guid>
      <description>&lt;h1&gt;
  
  
  🚀 New WJb Demo: Workflow Monitoring in Action
&lt;/h1&gt;

&lt;p&gt;Want to see what a complete workflow looks like in WJb?&lt;/p&gt;

&lt;p&gt;The new &lt;strong&gt;WJb.Demo.Monitor&lt;/strong&gt; sample demonstrates an end-to-end job pipeline with a live monitoring UI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpa4a5puuf7caarxao3lp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpa4a5puuf7caarxao3lp.png" alt="WJb Monitor" width="799" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Import Customers&lt;br&gt;&lt;br&gt;
✅ Generate Report&lt;br&gt;&lt;br&gt;
✅ Send Email&lt;br&gt;&lt;br&gt;
✅ Monitor execution in real time&lt;/p&gt;

&lt;p&gt;Run a single action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;wjb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EnqueueAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;ImportCustomersAction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ImportCustomersInput&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"CRM"&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WJb automatically chains the workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import-customers
        ↓
generate-report
        ↓
send-email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every step becomes visible in the monitoring dashboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the sample demonstrates
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Typed action inputs&lt;/li&gt;
&lt;li&gt;Constructor dependency injection&lt;/li&gt;
&lt;li&gt;Workflow chaining via &lt;code&gt;IAction.NextAsync(...)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Progress reporting&lt;/li&gt;
&lt;li&gt;Background job execution&lt;/li&gt;
&lt;li&gt;Real-time monitoring UI&lt;/li&gt;
&lt;li&gt;Job payload inspection&lt;/li&gt;
&lt;li&gt;Action discovery&lt;/li&gt;
&lt;li&gt;Service discovery&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Monitor Features
&lt;/h2&gt;

&lt;p&gt;The built-in Blazor monitor provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Job status tracking&lt;/li&gt;
&lt;li&gt;Progress visualization&lt;/li&gt;
&lt;li&gt;Execution history&lt;/li&gt;
&lt;li&gt;Payload inspection&lt;/li&gt;
&lt;li&gt;Registered actions&lt;/li&gt;
&lt;li&gt;Registered services&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why it is interesting
&lt;/h2&gt;

&lt;p&gt;The entire workflow is composed of small focused actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;import-customers&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;generate-report&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;send-email&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No workflow designer.&lt;/p&gt;

&lt;p&gt;No XML.&lt;/p&gt;

&lt;p&gt;No complex configuration.&lt;/p&gt;

&lt;p&gt;Just C# actions connected through explicit workflow transitions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample
&lt;/h2&gt;

&lt;p&gt;🔗 &lt;a href="https://github.com/UkrGuru/WJb.Demo/tree/main/samples/WJb.Demo.Monitor" rel="noopener noreferrer"&gt;https://github.com/UkrGuru/WJb.Demo/tree/main/samples/WJb.Demo.Monitor&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The sample includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Workflow execution&lt;/li&gt;
&lt;li&gt;Action chaining&lt;/li&gt;
&lt;li&gt;Progress reporting&lt;/li&gt;
&lt;li&gt;Live monitoring&lt;/li&gt;
&lt;li&gt;Payload inspection&lt;/li&gt;
&lt;li&gt;Actions explorer&lt;/li&gt;
&lt;li&gt;Services explorer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Perfect for understanding how WJb workflows behave in a real application.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>blazor</category>
      <category>aspnetcore</category>
    </item>
    <item>
      <title>🚀 WJb Monitor is coming together.</title>
      <dc:creator>Oleksandr Viktor</dc:creator>
      <pubDate>Wed, 15 Jul 2026 16:14:01 +0000</pubDate>
      <link>https://dev.to/ukrguru/wjb-monitor-is-coming-together-3imb</link>
      <guid>https://dev.to/ukrguru/wjb-monitor-is-coming-together-3imb</guid>
      <description>&lt;p&gt;Over the last few days I focused on completing the monitoring UI for WJb.&lt;/p&gt;

&lt;p&gt;Current state:&lt;/p&gt;

&lt;p&gt;✅ Jobs monitoring&lt;br&gt;
 ✅ Job details and payload viewer&lt;br&gt;
 ✅ Actions management&lt;br&gt;
 ✅ Services management&lt;br&gt;
 ✅ SQL Store integration&lt;br&gt;
 ✅ Real job execution testing&lt;br&gt;
 ✅ Retry and progress tracking&lt;br&gt;
 ✅ Responsive Blazor UI&lt;/p&gt;

&lt;p&gt;A few screenshots are attached, including an animated walkthrough of the application.&lt;/p&gt;

&lt;p&gt;One pleasant surprise during development: I completely removed the dependency on Bootstrap Icons. Navigation now uses lightweight SVG icons, while action buttons use simple Unicode symbols. The result is cleaner than expected and has zero external dependencies.&lt;/p&gt;

&lt;p&gt;The original plan also included a dashboard page, but after using the application in practice I decided to postpone it. The current feature set already delivers real value, and I'd rather gather experience from actual usage before adding metrics and analytics.&lt;/p&gt;

&lt;p&gt;The goal remains unchanged:&lt;/p&gt;

&lt;p&gt;🎯 WJb v1.0 Release&lt;/p&gt;

&lt;p&gt;Everything is progressing according to plan, and the first stable release is getting very close.&lt;/p&gt;

&lt;h1&gt;
  
  
  dotnet #csharp #blazor #opensource #softwaredevelopment #jobs #scheduler #microsoft #sqlserver #webdevelopment
&lt;/h1&gt;

</description>
      <category>backend</category>
      <category>dotnet</category>
      <category>sql</category>
    </item>
    <item>
      <title>🚀 New workflow samples added to WJb Demo (Blazor WASM)</title>
      <dc:creator>Oleksandr Viktor</dc:creator>
      <pubDate>Tue, 30 Jun 2026 08:35:11 +0000</pubDate>
      <link>https://dev.to/ukrguru/new-workflow-samples-added-to-wjb-demo-blazor-wasm-40l0</link>
      <guid>https://dev.to/ukrguru/new-workflow-samples-added-to-wjb-demo-blazor-wasm-40l0</guid>
      <description>&lt;p&gt;🚀 &lt;strong&gt;New workflow samples added to WJb Demo (Blazor WASM)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fspsup6jufxsmnp6kmhm1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fspsup6jufxsmnp6kmhm1.png" alt=" " width="800" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've just expanded the WJb demo application with two new workflow-focused samples:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Retry Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic retries with &lt;code&gt;JobOptions&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Retry delay configuration&lt;/li&gt;
&lt;li&gt;Workflow continuation after successful retry&lt;/li&gt;
&lt;li&gt;Demonstrates retry inheritance across chained actions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;Order Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-step business workflow&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CreateOrder → ReserveStock → ChargePayment → SendConfirmation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Progress reporting across workflow steps&lt;/li&gt;
&lt;li&gt;Action chaining via &lt;code&gt;ActionResults.Next(...)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Payload propagation between actions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These samples were added while building a new &lt;code&gt;WorkflowTests&lt;/code&gt; suite, which also helped uncover and fix several workflow engine issues, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dead-letter infinite loop scenarios&lt;/li&gt;
&lt;li&gt;Missing retry policy inheritance for chained actions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is a much stronger demonstration of how WJb can be used for real workflow orchestration rather than just background jobs.&lt;/p&gt;

&lt;p&gt;🔗 Demo source:&lt;br&gt;
&lt;a href="https://github.com/UkrGuru/WJb.Demo/tree/main/samples/WJb.Demo.Wasm" rel="noopener noreferrer"&gt;https://github.com/UkrGuru/WJb.Demo/tree/main/samples/WJb.Demo.Wasm&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  dotnet #csharp #blazor #opensource #workflow #backgroundjobs #aspnetcore #softwarearchitecture #testing #wasm #wjb #ukrguru
&lt;/h1&gt;

</description>
      <category>dotnet</category>
    </item>
  </channel>
</rss>
