Quartz.NET لـ C# (.NET): دليل شامل لجدولة المهام
Quartz.NET هي مكتبة قوية ومرنة ومفتوحة المصدر تُستخدم على نطاق واسع لجدولة المهام في تطبيقات .NET. تتيح للمطورين إنشاء وإدارة وتنفيذ المهام الخلفية وفقًا لجدول زمني محدد. سواء كنت بحاجة لتشغيل كود في وقت معين، أو بشكل دوري، أو استجابة لحدث ما (مثل مهام cron في Linux)، فإن Quartz.NET هو الخيار الأمثل. المكتبة هي نسخة من إطار العمل الشهير Quartz Scheduler الخاص بلغة Java.
لماذا تحتاج إليها؟ في التطوير الحديث، غالبًا ما تظهر مهام لا يجب تنفيذها بشكل متزامن بناءً على طلب المستخدم. قد تكون هذه المهام مثل إرسال البريد الإلكتروني الجماعي، تنظيف الملفات المؤقتة، مزامنة البيانات مع واجهات API خارجية، إنشاء التقارير، تحديث الذاكرة المؤقتة (Cache)، وغيرها الكثير. توفر Quartz.NET آلية موثوقة ومتسامحة مع الأخطاء لتنفيذ هذه المهام. تدعم حفظ حالة المهام في قاعدة البيانات (JobStore)، مما يسمح لها بالبقاء بعد إعادة تشغيل التطبيق، كما تدعم التجميع (Clustering) لتوزيع الحمل.
على عكس الاستخدام البسيط لـ System.Threading.Timer أو BackgroundService، تقدم Quartz.NET واجهة برمجة تطبيقات (API) غنية لإدارة دورة حياة المهام، ومشغلات معقدة (يوميًا، أسبوعيًا، باستخدام تعبيرات CRON)، والتنفيذ المتوازي، والاستماع للأحداث، وغير ذلك الكثير. هذا يجعلها المعيار الفعلي لجدولة المهام في نظام .NET البيئي.
التثبيت
يتم توزيع Quartz.NET عبر NuGet. للتثبيت، استخدم أحد الأوامر التالية في وحدة تحكم مدير الحزم:
# تثبيت الحزمة الأساسية
dotnet add package Quartz
# إذا كنت بحاجة لدعم تهيئة XML
dotnet add package Quartz.Plugins
# للاستخدام مع Dependency Injection (موصى به لـ ASP.NET Core)
dotnet add package Quartz.Extensions.Hosting
لإطار العمل الكلاسيكي .NET Framework (مثل .NET 4.8)، استخدم وحدة تحكم NuGet:
Install-Package Quartz
بداية سريعة: مثال عملي بسيط
لنقم بإنشاء تطبيق وحدة تحكم بسيط يطبع "Hello, Quartz!" كل 5 ثوانٍ.
using System;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
namespace QuartzQuickStart
{
// 1. إنشاء Job (مهمة)
public class HelloJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
await Console.Out.WriteLineAsync($"Hello, Quartz! الوقت: {DateTime.Now:HH:mm:ss}");
}
}
class Program
{
static async Task Main(string[] args)
{
// 2. إنشاء مصنع المجدول
StdSchedulerFactory factory = new StdSchedulerFactory();
// 3. الحصول على المجدول
IScheduler scheduler = await factory.GetScheduler();
// 4. بدء تشغيل المجدول
await scheduler.Start();
// 5. تعريف المهمة (Job)
IJobDetail job = JobBuilder.Create()
.WithIdentity("myJob", "group1")
.Build();
// 6. تعريف المشغل (الجدول الزمني)
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("myTrigger", "group1")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(5)
.RepeatForever())
.Build();
// 7. تسجيل المهمة والمشغل في المجدول
await scheduler.ScheduleJob(job, trigger);
// 8. الانتظار لمنع إغلاق وحدة التحكم
await Task.Delay(TimeSpan.FromSeconds(30));
// 9. إيقاف المجدول
await scheduler.Shutdown();
}
}
}