Skip to content

QuartzVsHangfire: Quartz.NET 4.1.0 and Hangfire 1.8.25 - #2220

Merged
vladimir-pecanac-main merged 1 commit into
CodeMazeBlog:mainfrom
vladimir-pecanac-main:seo/101079-quartz4
Sep 17, 2026
Merged

vladimir-pecanac-main merged 1 commit into
CodeMazeBlog:mainfrom
vladimir-pecanac-main:seo/101079-quartz4

Conversation

@vladimir-pecanac-main

Copy link
Copy Markdown
Collaborator

Moves the dotnet-client-libraries/QuartzVsHangfire sample to Quartz.NET 4.1.0 and Hangfire 1.8.25, for the refreshed "Hangfire vs Quartz.NET: Which Scheduler to Choose?" article.

Quartz.NET 4 closed the two gaps the article's verdict was scored on, so the sample now demonstrates both rather than the workarounds around them.

Packages

Package Was Now
Quartz 3.19.1 4.1.0
Quartz.Extensions.Hosting 3.19.1 removed (4.1.0 is an empty forwarding package; AddQuartzHostedService is in Quartz)
Quartz.Dashboard not referenced 4.1.0
Hangfire.Core, Hangfire.NetCore 1.8.24 1.8.25
Newtonsoft.Json transitive 11.0.1 13.0.4 explicit

The Newtonsoft.Json pin is not cosmetic: Hangfire.Core 1.8.25 still depends on Newtonsoft.Json >= 11.0.1, which raises NU1903 (known high severity advisory). The pin is the reason the build reports 0 warnings.

FrameworkReference Include="Microsoft.AspNetCore.App" is required because Quartz.Dashboard carries that framework reference in its own nuspec; without it the restore fails.

Code

  • IJob.Execute and every IJobListener member move to ValueTask plus a CancellationToken (BackgroundJob, ReportJob, QuartzRetryJob, LoggingJobListener).
  • BackgroundJob reads its optional flag with TryGetBoolean: on 4.x GetBoolean throws InvalidCastException for a missing key where 3.x threw KeyNotFoundException.
  • QuartzStorageConfig drops StdSchedulerFactory and the NameValueCollection property bag, both removed in 4.x, for QuartzSchedulerBuilder.
  • QuartzStartup uses the configurator overload of AddJob<T>; the JobKey overload no longer compiles (CS1503).
  • QuartzRetryJob loses the manual refire workaround. New QuartzRetryPolicyScheduler puts the retry schedule on the trigger with RetryPolicy.Explicit and RetryPolicy.Exponential.
  • New QuartzDashboardSetup registers AddQuartzDashboard and AddQuartzExecutionHistory and maps the dashboard.
  • Two comment-only fixes carried over from PR Hangfire vs Quartz.NET: remove the em dashes from three sample comments #2190 (HangfireMonitoring, and the comments in LoggingJobListener / QuartzStorageConfig that this change rewrites anyway).

Tests

Tests/QuartzRetryJobTests.cs is renamed to Tests/QuartzRetryPolicySchedulerTests.cs and rewritten, because the behaviour it asserted is the workaround this change removes. Tests/QuartzDashboardSetupTests.cs is new.

Verified on SDK 10.0.302, runtime Microsoft.NETCore.App 10.0.10:

  • dotnet build QuartzVsHangfire.sln -c Release: 0 Warning(s), 0 Error(s)
  • dotnet test QuartzVsHangfire.sln -c Release --no-build: Passed! Failed: 0, Passed: 17, Skipped: 0, Total: 17 (up from 15)
  • dotnet run --project QuartzVsHangfire -c Release: both sample lines print as before

This supersedes #2190, which touched three comment lines in this same folder.

Quartz.NET 4 closes the two gaps this comparison was scored on, so the sample
now shows both: the retry policy that lives on the trigger, and the first-party
Quartz.Dashboard package.

- Quartz 3.19.1 to 4.1.0, and Quartz.Extensions.Hosting dropped (4.1.0 is an
  empty forwarding package; AddQuartzHostedService is in Quartz now).
- Hangfire.Core and Hangfire.NetCore 1.8.24 to 1.8.25.
- Newtonsoft.Json pinned to 13.0.4: the transitive 11.0.1 raises NU1903.
- IJob.Execute and every IJobListener member move to ValueTask plus a
  CancellationToken.
- StdSchedulerFactory and the NameValueCollection property bag are gone, so the
  standalone scheduler is built with QuartzSchedulerBuilder.
- QuartzRetryJob drops the manual refire workaround; QuartzRetryPolicyScheduler
  carries the explicit and exponential retry policies instead.
- QuartzDashboardSetup registers the dashboard and the execution history.

dotnet build -c Release: 0 warnings, 0 errors. dotnet test: 17 of 17 passed.
@vladimir-pecanac-main
vladimir-pecanac-main merged commit 29afa51 into CodeMazeBlog:main Sep 17, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant