Quartz.NET 예약 작업
Quartz.NET으로 작업과 트리거를 정의하고 크론 식을 사용하며 ASP.NET Core DI와 통합합니다.
Quartz.NET 예약 작업은(는) CoddyKit의 무료 C# Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C# Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
Quartz.NET을 사용하는 이유
cron 식, 작업 영속성, 클러스터링, 재시도 정책 및 작업 체인이 필요할 때 Quartz.NET은 PeriodicTimer보다 뛰어난 운영 환경용 스케줄러를 제공합니다. 널리 사용되는 Java Quartz 스케줄러를 .NET으로 포팅한 것입니다.
Quartz.NET 설치
Quartz 및 Quartz.AspNetCore 패키지를 추가합니다. ASP.NET 통합 기능이 스케줄러를 호스팅 서비스로 자동 등록합니다.
# Install packages
dotnet add package Quartz
dotnet add package Quartz.AspNetCore
# Optional: persistence (requires Quartz.Serialization.Json too)
# dotnet add package Quartz.Jobs
# dotnet add package Quartz.Plugins작업 정의하기
IJob(또는 최신 Quartz의 경우 IAsyncJob)을 구현하고 Execute 메서드를 작성합니다. 작업 컨텍스트는 런타임 데이터와 현재 트리거 정보를 제공합니다.
using Quartz;
[DisallowConcurrentExecution] // prevent overlapping executions
public class ReportGeneratorJob : IJob
{
private readonly IReportService _reports;
private readonly ILogger<ReportGeneratorJob> _logger;
public ReportGeneratorJob(IReportService r, ILogger<ReportGeneratorJob> l)
{ _reports = r; _logger = l; }
public async Task Execute(IJobExecutionContext context)
{
_logger.LogInformation("Generating report at {Time}", DateTime.UtcNow);
await _reports.GenerateDailyReportAsync(context.CancellationToken);
_logger.LogInformation("Report generated");
}
}ASP.NET Core에 Quartz 등록
AddQuartz로 스케줄러를 구성하고 AddQuartzHostedService로 IHostedService로 실행되도록 합니다. 람다 식에서 작업과 트리거를 구성합니다.
builder.Services.AddQuartz(q =>
{
q.UseMicrosoftDependencyInjectionJobFactory();
var jobKey = new JobKey("ReportGenerator");
q.AddJob<ReportGeneratorJob>(opts => opts.WithIdentity(jobKey));
q.AddTrigger(opts => opts
.ForJob(jobKey)
.WithIdentity("ReportTrigger")
.WithCronSchedule("0 0 8 * * ?") // 8:00 AM daily
);
});
builder.Services.AddQuartzHostedService(q =>
q.WaitForJobsToComplete = true);Cron 식 구문
Quartz는 6개 또는 7개 필드로 이루어진 cron 식을 사용합니다: seconds minutes hours day-of-month month day-of-week [year]. Quartz cron은 Unix cron과 조금 다르며 초가 맨 앞에 옵니다.
// Quartz cron format: sec min hour dom month dow [year]
"0 0 8 * * ?" // Every day at 8:00 AM
"0 0/30 9-17 * * ?" // Every 30 min, 9 AM - 5 PM weekdays
"0 0 0 1 * ?" // First day of every month at midnight
"0 0 6 ? * MON-FRI" // Every weekday at 6 AM
"0 0/5 * * * ?" // Every 5 minutes
// Tip: use cronmaker.com or crontab.guru to build expressions단순 트리거
cron의 복잡성 없이 간격 기반 일정을 사용하려면 WithSimpleSchedule을 사용한 단순 트리거를 사용하세요.
q.AddTrigger(opts => opts
.ForJob(jobKey)
.WithIdentity("CleanupTrigger")
.StartNow()
.WithSimpleSchedule(s => s
.WithIntervalInHours(1)
.RepeatForever())
);
// Or a one-shot trigger:
q.AddTrigger(opts => opts
.ForJob(jobKey)
.WithIdentity("OneShot")
.StartAt(DateTimeOffset.UtcNow.AddMinutes(5)));작업 데이터 맵
JobDataMap을 통해 런타임 매개 변수를 작업에 전달합니다. context.JobDetail.JobDataMap을 사용하면 Execute 내부에서 해당 매개 변수에 액세스할 수 있습니다.
q.AddJob<EmailJob>(opts => opts
.WithIdentity("EmailJob")
.UsingJobData("to", "admin@example.com")
.UsingJobData("subject", "Daily Digest"));
// Inside the job:
public async Task Execute(IJobExecutionContext context)
{
var to = context.JobDetail.JobDataMap.GetString("to");
var subject = context.JobDetail.JobDataMap.GetString("subject");
await _mailer.SendAsync(to!, subject!, "body");
}DisallowConcurrentExecution
[DisallowConcurrentExecution]은 이전 작업 인스턴스가 아직 실행 중일 때 새 작업 인스턴스가 시작되지 않도록 합니다. 공유 리소스에 액세스하는 작업에 필수적입니다.
[DisallowConcurrentExecution]
public class InventorySyncJob : IJob
{
// If a sync takes > 1 minute and triggers every minute,
// the next trigger is delayed until this one completes
public async Task Execute(IJobExecutionContext context)
{
await SyncInventoryAsync(context.CancellationToken);
}
}
// Without [DisallowConcurrentExecution], multiple instances
// could run in parallel, causing data conflicts.예외 처리 및 재시도
작업 코드를 try/catch로 감싸세요. JobExecutionException을 발생시키면 Quartz에 작업을 즉시 또는 지연 후 다시 실행하라고 알릴 수 있습니다.
public async Task Execute(IJobExecutionContext context)
{
try
{
await ProcessAsync(context.CancellationToken);
}
catch (TransientException ex)
{
// Ask Quartz to retry immediately
var jobException = new JobExecutionException(ex)
{
RefireImmediately = true
};
throw jobException;
}
catch (Exception ex)
{
_logger.LogError(ex, "Job failed — not retrying");
// Don't rethrow — job is done
}
}실전: 여러 작업 스케줄러
서로 다른 일정으로 실행되는 여러 작업을 포함하고, 모든 서비스에 DI를 사용하는 운영 환경용 Quartz 구성입니다.
builder.Services.AddQuartz(q =>
{
q.UseMicrosoftDependencyInjectionJobFactory();
// Daily report at 8 AM
var reportKey = new JobKey("DailyReport");
q.AddJob<ReportGeneratorJob>(o => o.WithIdentity(reportKey));
q.AddTrigger(o => o.ForJob(reportKey)
.WithCronSchedule("0 0 8 * * ?"));
// Inventory sync every 15 minutes
var syncKey = new JobKey("InventorySync");
q.AddJob<InventorySyncJob>(o => o.WithIdentity(syncKey));
q.AddTrigger(o => o.ForJob(syncKey)
.WithSimpleSchedule(s => s
.WithIntervalInMinutes(15)
.RepeatForever()));
// Cache cleanup every night at 2 AM
var cacheKey = new JobKey("CacheCleanup");
q.AddJob<CacheCleanupJob>(o => o.WithIdentity(cacheKey));
q.AddTrigger(o => o.ForJob(cacheKey)
.WithCronSchedule("0 0 2 * * ?"));
});빠른 확인
Quartz.NET 작업에 [DisallowConcurrentExecution] 특성을 적용하면 어떤 동작을 합니까?
복습: Quartz.NET 예약 작업
핵심 요점:
- Quartz.NET: cron, 영속성 및 클러스터링을 지원하는 운영 환경용 스케줄러
- IJob을 구현하고 Execute 메서드를 정의하여 작업을 만듭니다
- AddQuartz + AddQuartzHostedService로 등록하며 작업은 DI를 인식합니다
- cron 형식: 초 분 시 일자 월 요일 — 초가 먼저 나오는 점에 유의합니다
[DisallowConcurrentExecution]: 다시 실행하기 전에 현재 실행이 완료될 때까지 기다립니다- JobDataMap을 사용하여 런타임 매개 변수를 작업에 전달합니다
AI 튜터와 함께 C#을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 93
- 레슨
- 346
자주 묻는 질문
“Quartz.NET 예약 작업” 강의는 무료인가요?
네 — “Quartz.NET 예약 작업” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C# Academy 강의 전체를 잠금 해제할 수 있습니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“Quartz.NET 예약 작업”에서 뭘 배우나요?
Quartz.NET으로 작업과 트리거를 정의하고 크론 식을 사용하며 ASP.NET Core DI와 통합합니다. 브라우저에서 직접 실행하는 실습 코드로 C# Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
C# Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 C# Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“Quartz.NET 예약 작업” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 C# Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 C# Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- IHostedService와 BackgroundService
- Worker Service 프로젝트
- 주기적 작업과 타이머
- Quartz.NET 예약 작업