Task Scheduler in C# (.NET): Quartz.NET and System.Threading.Timer

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Task Scheduler in C# (.NET): From a Simple Timer to Industrial Quartz.NET

A Task Scheduler is an essential part of any serious application. Whether it's periodic cache cleanup, sending email newsletters, or synchronizing data with an external API, a reliable mechanism for performing background operations is indispensable. In the .NET ecosystem, developers have several approaches available: from the built-in System.Threading.Timer to the powerful and flexible Quartz.NET framework. In this article, we will cover both options, show code examples, and help you choose the right tool for your project.



1. Built-in System.Threading.Timer

The simplest and lightest way to run a scheduled task is to use System.Threading.Timer. It does not require installing third-party packages and is ideal for simple scenarios: executing a method at fixed intervals or a one-time delay.



Example: executing a task every 5 seconds

using System;using System.Threading;

class Program{ static void Main() { // Create a timer that runs the callback every 5 seconds Timer timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(5)); Console.WriteLine("Timer started. Press Enter to exit."); Console.ReadLine(); timer.Dispose(); }

static void DoWork(object state) { Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] Executing background task..."); }}

Pros:

  • Built into .NET, no additional libraries needed.
  • Minimal resource consumption.
  • Ease of use.

Cons:

  • No built-in support for CRON expressions.
  • Difficult to manage multiple tasks with different schedules.
  • No persistence mechanisms (tasks are lost on restart).
  • The callback runs on a thread from the pool, potential synchronization issues.

For educational projects and simple utilities, System.Threading.Timer is an excellent choice. However, for production applications with dozens of tasks, it's worth looking at more advanced solutions.



2. Quartz.NET — Industrial Task Scheduler

Quartz.NET is a powerful, flexible, and mature framework for task scheduling in .NET. It is inspired by the popular Java counterpart Quartz and supports:

  • CRON expressions for flexible scheduling (every other hour, weekdays at 9:00, etc.).
  • Task persistence (saving to a database).
  • Clustering (multiple servers can execute tasks).
  • Misfire handling.
  • Child tasks and triggers.


Installing Quartz.NET

Install the package via NuGet:

dotnet add package Quartz


Example: a simple task with a CRON schedule

using System;using System.Threading.Tasks;using Quartz;using Quartz.Impl;

class Program{ static async Task Main() { // Create a scheduler StdSchedulerFactory factory = new StdSchedulerFactory(); IScheduler scheduler = await factory.GetScheduler(); await scheduler.Start();

// Define the job IJobDetail job = JobBuilder.Create<HelloJob>() .WithIdentity("helloJob", "group1") .Build();

// Create a trigger: every day at 10:30 AM ITrigger trigger = TriggerBuilder.Create() .WithIdentity("trigger1", "group1") .WithCronSchedule("0 30 10 ? * * *") // CRON: second, minute, hour, day, month, day of week .Build();

// Register the job with the trigger await scheduler.ScheduleJob(job, trigger);

Console

Recommendations