TGViewer
C# Geeks (.NET) C# Geeks (.NET) @csharpgeeks · 548 subscribers
Post #175 130
زمان‌بندی Background Jobها با Quartz.NET ⏱️


اگر در حال ساخت یک اپلیکیشن مقیاس‌پذیر هستید، یک نیازمندی رایج این است که برخی از کارها را در اپلیکیشن خود به یک background job منتقل کنید.

در اینجا چند مثال از آن آمده است:

📧 ارسال نوتیفیکیشن‌های ایمیل
📊 تولید گزارش‌ها
🔄 به‌روزرسانی یک کش
🖼 پردازش تصویر

🤔چگونه می‌توانید یک background job تکرارشونده در NET. ایجاد کنید؟


Quartz.NET
یک سیستم زمان‌بندی job کامل و متن‌باز است که می‌تواند از کوچکترین اپلیکیشن‌ها تا سیستم‌های بزرگ سازمانی استفاده شود.

سه مفهوم وجود دارد که باید در Quartz.NET درک کنید:

Job 📝
تسک پس‌زمینه‌ای واقعی که می‌خواهید اجرا کنید.

Trigger ⏰
تریگری که زمان اجرای یک job را کنترل می‌کند.

Scheduler 🧠
مسئول هماهنگی jobها و تریگرها.

بیایید ببینیم چگونه می‌توانیم از Quartz.NET برای ایجاد و زمان‌بندی background jobها استفاده کنیم.

افزودن سرویس میزبانی شده Quartz.NET 🔧

اولین کاری که باید انجام دهیم، نصب پکیج NuGet Quartz.NET است.

Install-Package Quartz.Extensions.Hosting

دلیل استفاده ما از این کتابخانه این است که به خوبی با NET. با استفاده از یک نمونه IHostedService یکپارچه می‌شود.
برای راه‌اندازی سرویس میزبانی شده Quartz.NET، به دو چیز نیاز داریم:

افزودن سرویس‌های مورد نیاز به کانتینر DI.
services.AddQuartz(configure =>
{
configure.UseMicrosoftDependencyInjectionJobFactory();
});

services.AddQuartzHostedService(options =>
{
options.WaitForJobsToComplete = true;
});

Quartz.NET
با واکشی jobها از کانتینر DI، آن‌ها را ایجاد می‌کند. این همچنین به این معنی است که شما می‌توانید از سرویس‌های scoped در jobهای خود استفاده کنید، نه فقط سرویس‌های singleton یا transient.
تنظیم گزینه WaitForJobsToComplete روی true تضمین می‌کند که Quartz.NET قبل از خروج، منتظر بماند تا jobها به آرامی تکمیل شوند.

ایجاد Background Job با IJob 👨‍💻

برای ایجاد یک background job با Quartz.NET باید اینترفیس IJob را پیاده‌سازی کنید.
این اینترفیس فقط یک متد واحد - Execute - را ارائه می‌دهد که می‌توانید کد background job خود را در آن قرار دهید.

💡چند نکته قابل توجه در اینجا:


ما از DI برای تزریق سرویس‌های ApplicationDbContext و IPublisher استفاده می‌کنیم.

Job
با DisallowConcurrentExecution دکوریت شده تا از اجرای همزمان همان job جلوگیری شود.
[DisallowConcurrentExecution]
public class ProcessOutboxMessagesJob : IJob
{
private readonly ApplicationDbContext _dbContext;
private readonly IPublisher _publisher;

public ProcessOutboxMessagesJob(
ApplicationDbContext dbContext,
IPublisher publisher)
{
_dbContext = dbContext;
_publisher = publisher;
}

public async Task Execute(IJobExecutionContext context)
{
List<OutboxMessage> messages = await _dbContext
.Set<OutboxMessage>()
.Where(m => m.ProcessedOnUtc == null)
.Take(20)
.ToListAsync(context.CancellationToken);

foreach (OutboxMessage outboxMessage in messages)
{
IDomainEvent? domainEvent = JsonConvert
.DeserializeObject<IDomainEvent>(
outboxMessage.Content,
new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
});

if (domainEvent is null)
{
continue;
}

await _publisher.Publish(domainEvent, context.CancellationToken);

outboxMessage.ProcessedOnUtc = DateTime.UtcNow;
await _dbContext.SaveChangesAsync();
}
}
}


حالا که background job آماده است، باید آن را در کانتینر DI ثبت کرده و یک تریگر اضافه کنیم که job را اجرا کند.
More from @csharpgeeks
  1. Sep 22, 2026یه مدتی قراره از دنیای NET. فاصله بگیرم، چون وقتشه برم سربازی. راستش نمیدونم این مدت رو چج…
  2. Sep 20, 2026🔥 حالا مشکل اصلی: Alert Storm فرض کن Database از دسترس خارج شده. ۱۰۰ Pod داری. هر Pod می‌…
  3. Sep 20, 2026🚨 طراحی سیستم Monitoring و Alerting در یک سیستم بزرگ فرض کن ساعت ۳ صبح است. سیستم شما با…
  4. Sep 19, 2026#Engineering_Leadership تصمیم نگرفتن هم یک تصمیم است یه چیز عجیب توی تیم‌های مهندسی: گاهی…
  5. Sep 19, 2026☑ چک‌لیست آماده‌سازی تیم، فرایندها و زیرساخت برای توسعه با AI توجه: هیچ چک‌لیستی جهان‌شمول…
  6. Sep 19, 2026📌پایان یک انتظار طولانی: اعتبارسنجی ناهمگام (Async Validation) در NET 11.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →