🧾 Scenario: Daily Invoice Email at 9 AM Local Time

Requirements:

🔧 Quartz.NET vs Hangfire (Quick Comparison)

FeatureHangfireQuartz.NET
Time Zone Support❌ Manual✅ Native
Ideal ForDelayed jobsScheduled jobs
Dashboard✅ Yes❌ No
Retry/Error Handling✅ Yes⚠️ Manual
Distributed Setup✅ Yes✅ Yes

🛠️ Option 1: Quartz.NET for Time-Sensitive Jobs

Best for scheduled tasks at specific times in specific time zones

📦 Job Class

public class InvoiceJob : IJob
{
    public Task Execute(IJobExecutionContext context)
    {
        Console.WriteLine($"Invoice job running at {DateTime.UtcNow}");
        // Custom logic: fetch users in IST and send emails
        return Task.CompletedTask;
    }
}

🗓️ Register Job in Program.cs (or a Hosted Service)

IScheduler scheduler = await StdSchedulerFactory.GetDefaultScheduler();
await scheduler.Start();

IJobDetail job = JobBuilder.Create<InvoiceJob>()
    .WithIdentity("invoiceJob", "billing")
    .Build();

ITrigger trigger = TriggerBuilder.Create()
    .WithIdentity("dailyTrigger", "billing")
    .WithCronSchedule("0 0 9 ? * *", x => x
        .InTimeZone(TimeZoneInfo.FindSystemTimeZoneById("India Standard Time")))
    .Build();

await scheduler.ScheduleJob(job, trigger);

✅ This job runs daily at 9 AM IST, no matter where your server is hosted.

🛠️ Option 2: Hangfire for Delayed or Event-Based Jobs

Best for fire-and-forget or delayed jobs

📦 Delayed Job Example

BackgroundJob.Schedule(() => SendEmail(userId), TimeSpan.FromMinutes(10));

📦 Recurring Job Example

RecurringJob.AddOrUpdate(
    "daily-invoice",
    () => SendDailyInvoices(),
    Cron.Daily
);

⚠️ Time Zone Limitation: Hangfire schedules in server time.

To support multiple time zones:

🏗️ Run Jobs on a Separate Server

Both Quartz.NET and Hangfire can run in a dedicated .NET 6 Worker Service:

+-------------------+      +-------------------------+
| Web API           | -->  | .NET 6 Worker (Jobs)    |
+-------------------+      +-------------------------+
         Database             Job Scheduling Engine

✅ This setup improves scalability, separation of concerns, and distributed job processing.

🎯 Which Should You Use?

Use CaseBest Choice
Time-specific jobs in user time zones✅ Quartz.NET
Delayed jobs or event-driven triggers✅ Hangfire
Need dashboard, retries, failure tracking✅ Hangfire
Hybrid needs (scheduled + triggered)✅ Use both

✅ Best Practices